一、什么是微服務網關(API Gateway)
定義:微服務網關是整個系統請求的統一入口,負責請求轉發、過濾處理、安全校驗等。
作用:
請求路由
日志記錄
權限控制
參數校驗
解決跨域問題
黑白名單控制
限流、熔斷、降級
統一前后端接口調用
二、過濾器與網關的區別
對比項 過濾器(Filter) 網關(Gateway) 作用范圍 單個微服務內部 整個微服務系統 實現方式 @WebFilter、OncePerRequestFilter Spring Cloud Gateway 適用場景 局部處理、日志、攔截器 全局處理、統一入口、鑒權
三、Zuul vs Gateway
對比項 Zuul(1代網關) Gateway(2代網關) 所屬公司 Netflix Spring 官方 技術架構 Servlet、阻塞式 WebFlux、非阻塞響應式 性能 較差 高性能、支持長連接 生態整合 較弱 完美整合 Spring 生態 適合場景 兼容性要求高的舊項目 新項目優選、高并發場景
四、快速構建 Gateway 項目
Maven 依賴
//注意:會和spring-webmvc的依賴沖突,需要排除spring-webmvc <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency>
????????在使用
spring-cloud-starter-gateway
時,不能再同時使用spring-boot-starter-web
,否則會產生沖突或運行時報錯。
? 原因詳解
🔧
spring-cloud-starter-gateway
是基于 Spring WebFlux(響應式編程)
內部依賴的是
spring-boot-starter-webflux
使用響應式的非阻塞式 Netty 服務器(不是 Tomcat)
框架核心類如:
WebHandler
、ServerWebExchange
、Mono
、Flux
?
spring-boot-starter-web
是基于 Spring MVC(Servlet 阻塞式編程)
內部使用的是
spring-web + spring-webmvc
默認使用嵌入式 Tomcat
與 WebFlux 核心機制不兼容
application.yml 配置
server:port: 80spring:application:name: gateway-servicecloud:gateway:discovery: //二選一locator:enabled: true # 開啟服務注冊自動路由routes: //二選一- id: example-routeuri: http://www.example.com/predicates:- Path=/example/**
?
discovery.locator.enabled: true
(自動路由)
會自動將注冊中心的服務映射成路由,無需手動配置。
訪問格式:
http://網關地址/服務名/**
適合:快速開發、測試環境。
不靈活:路徑固定為服務名,不能自定義。
? 手動配置
routes
你手動指定路由規則(路徑、服務名、過濾器等)。
更靈活:可以自定義路徑、加過濾器、權限控制等。
適合:生產環境。
? 是否二選一?
一般只用一個即可。
正式環境推薦:關閉
discovery.locator.enabled
,手動寫routes
。
五、整合 Nacos 實現服務注冊與發現
添加依賴
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency>
application.yml 示例
spring:cloud:nacos:discovery:server-addr: 127.0.0.1:8848gateway:discovery:locator:enabled: trueroutes:- id: memberuri: lb://member-servicepredicates:- Path=/member/**filters:- StripPrefix=1
? 兩種
uri
寫法的區別🟩 第一種:
routes:- id: user-serviceuri: lb://user-servicepredicates:- Path=/user/**
解釋:
uri: lb://user-service
表示使用服務發現 + 負載均衡。
lb://
前綴 = load balancer,Spring Cloud Gateway 會去注冊中心(如 Nacos)里找名為user-service
的服務,并自動負載均衡調用。這個寫法 必須依賴 Nacos 或其他服務注冊中心,否則會報錯:服務找不到。
🟩 第二種:
routes:- id: example-routeuri: http://www.example.com/predicates:- Path=/example/**
解釋:
uri: http://...
表示直接轉發到固定的 HTTP 地址。不需要注冊中心,Gateway 會將請求直接轉發到
www.example.com
。不需要 Nacos 等服務發現組件。
? 總結對比表
配置方式 是否需要注冊中心(如 Nacos) 說明 uri: lb://user-service
? 需要 從注冊中心獲取服務實例,負載均衡 uri: http://www.example.com/
? 不需要 直接轉發到固定地址
? 最常用的判斷邏輯
是否用到了
lb://
?如果用到了,就需要服務注冊中心(Nacos)。否則不需要。
六、Nginx 與 Gateway 的區別
項目 Nginx Spring Cloud Gateway 編程語言 C語言 Java 擴展性 靠 Lua 二次開發 基于 Java/Spring 插件式開發 所屬層級 網絡層(L7)反向代理 微服務層 適合 高性能網絡轉發 服務間通信、認證授權、動態路由
七、自定義全局過濾器(如 Token 攔截)
想要了解更多過濾器的知識可以去看博主的另一篇文章的第四節有講解及小例子
分布式微服務--GateWay(補充)-CSDN博客
@Component public class TokenFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String token = exchange.getRequest().getQueryParams().getFirst("token");if (token == null || token.isEmpty()) {ServerHttpResponse response = exchange.getResponse();response.setStatusCode(HttpStatus.BAD_REQUEST);DataBuffer buffer = response.bufferFactory().wrap("token not is null".getBytes());return response.writeWith(Mono.just(buffer));}return chain.filter(exchange);} }
八、接口安全措施總結
冪等性控制:使用 token 防重復提交
HTTPS 加密傳輸
MD5 簽名防篡改
API 權限控制(白名單、黑名單、OAuth2)
熔斷、降級、隔離防止雪崩
Swagger 文檔統一管理
九、網關高可用架構
使用 Nginx / LVS + Gateway 實現高可用網關
網關本身無狀態,可水平擴展
示例 Nginx 配置:
upstream gateway_cluster {server 127.0.0.1:8081;server 127.0.0.1:8082; }server {listen 80;server_name gateway.example.com;location / {proxy_pass http://gateway_cluster;} }
🔁 十、動態路由實現(基于數據庫)
表結構
CREATE TABLE boyatop_gateway (id INT AUTO_INCREMENT PRIMARY KEY,route_id VARCHAR(50),route_name VARCHAR(255),route_pattern VARCHAR(255),route_type VARCHAR(10),route_url VARCHAR(255) );
核心代碼
public void loadRoute(GateWayEntity gateway) {RouteDefinition definition = new RouteDefinition();definition.setId(gateway.getRouteId());PredicateDefinition predicate = new PredicateDefinition();predicate.setName("Path");predicate.addArg("pattern", gateway.getRoutePattern());FilterDefinition filter = new FilterDefinition();filter.setName("StripPrefix");filter.addArg("_genkey_0", "1");URI uri = gateway.getRouteType().equals("0") ?UriComponentsBuilder.fromUriString("lb://" + gateway.getRouteUrl()).build().toUri(): UriComponentsBuilder.fromHttpUrl(gateway.getRouteUrl()).build().toUri();definition.setUri(uri);definition.setPredicates(List.of(predicate));definition.setFilters(List.of(filter));routeDefinitionWriter.save(Mono.just(definition)).subscribe();publisher.publishEvent(new RefreshRoutesEvent(this)); }
🔄 十一、謂詞(斷言)與過濾器
謂詞(Predicates):判斷是否匹配請求
Path=/xxx/**
After=時間
Host=xxx.example.com
Method=GET
Header=X-Request-Id, \d+
Weight=group1, 2
過濾器(Filters):處理請求前/后邏輯
StripPrefix=1
AddRequestHeader=X-Name, value
RewritePath=/old/(?<segment>.*), /new/${segment}
Retry、CircuitBreaker
🌍 十二、解決跨域問題(CORS)
全局跨域過濾器實現
@Component public class CorsFilter implements GlobalFilter {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {ServerHttpResponse response = exchange.getResponse();HttpHeaders headers = response.getHeaders();headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "*");headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");return chain.filter(exchange);} }
🔬 十三、源碼啟動流程(核心組件)
GatewayClassPathWarningAutoConfiguration:校驗是否依賴 webflux
GatewayAutoConfiguration:加載所有核心 Bean(如 RouteDefinitionLocator)
RoutePredicateHandlerMapping:路由匹配
FilteringWebHandler:執行過濾器鏈
GatewayFilterChain:按順序執行自定義/內置過濾器
GatewayLoadBalancerClientAutoConfiguration:整合負載均衡器
GatewayRedisAutoConfiguration:限流配置
GatewayDiscoveryClientAutoConfiguration:注冊中心服務發現
🧠 十四、常見錯誤總結
錯誤:
required a bean of type 'org.springframework.http.codec.ServerCodecConfigurer'
原因:Spring Cloud Gateway 使用 webflux,請刪除 spring-boot-starter-web 依賴,使用
spring-boot-starter-webflux
📚 十五、關鍵詞匯速查表
名稱 說明 Route 路由配置(包含 id、uri、predicates、filters) Predicate 請求匹配規則(Path、Method、Header、Host) Filter 請求過濾器,可修改請求/響應 lb:// 使用服務名轉發(注冊中心) StripPrefix 去除路徑前綴 RefreshRoutesEvent 動態刷新路由事件
📎 官方參考文檔
Spring Cloud Gateway