Spring Cloud Gateway 網(wǎng)關(guān)非常實(shí)用的八個(gè)開發(fā)技巧,太實(shí)用了
環(huán)境:SpringBoot2.7.18 + SpringCloud Gateway2021.0.7
1. 簡(jiǎn)介
Spring Cloud Gateway是Spring Cloud生態(tài)系統(tǒng)中的官方API網(wǎng)關(guān)解決方案,它構(gòu)建在Spring Framework 5、Spring Boot以及Project Reactor之上,旨在為微服務(wù)架構(gòu)提供動(dòng)態(tài)路由、監(jiān)控、彈性、請(qǐng)求限流、路徑重寫、過(guò)濾等功能。作為Zuul的替代方案,Spring Cloud Gateway具備非阻塞、異步的特性,能夠處理高并發(fā)的請(qǐng)求。
Spring Cloud Gateway提供了靈活的網(wǎng)關(guān)解決方案,允許開發(fā)者通過(guò)簡(jiǎn)單的配置實(shí)現(xiàn)路由、負(fù)載均衡、安全認(rèn)證、限流、監(jiān)控和日志等功能。它支持多種路由策略,包括基于路徑、請(qǐng)求參數(shù)、請(qǐng)求頭、主機(jī)等的路由,并預(yù)置了許多常用的過(guò)濾器,如請(qǐng)求限流、熔斷器等,也支持自定義過(guò)濾器。
Spring Cloud Gateway基于Actuator提供了一些非常實(shí)用的API幫助管理API接口。引入Actuator依賴后就可以直接使用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2. 實(shí)戰(zhàn)案例
2.1 查看路由詳細(xì)信息
Spring Cloud Gateway添加了一種新的、更詳細(xì)的格式。它為每個(gè)路由添加了更多的細(xì)節(jié),讓你可以查看與每個(gè)路由關(guān)聯(lián)的謂詞和過(guò)濾器以及任何可用的配置。接口/actuator/gateway/route的示例如下:
[
{
"predicate": "Paths: [/cloud-gateway/**], match trailing slash: true",
"metadata": {
"nacos.instanceId": null,
"nacos.weight": "1.0",
"nacos.cluster": "DEFAULT",
"nacos.ephemeral": "true",
"nacos.healthy": "true",
"management.port": "8188",
"preserved.register.source": "SPRING_CLOUD"
},
"route_id": "ReactiveCompositeDiscoveryClient_cloud-gateway",
"filters": [
"[[StripPrefix parts = 1], order = 1]",
"[[RewritePath /cloud-gateway/?(?<remaining>.*) = '/${remaining}'], order = 1]"
],
"uri": "lb://cloud-gateway",
"order": 0
},
...
]
通過(guò)如下配置可以關(guān)閉此功能
spring:
cloud:
gateway:
actuator:
verbose:
enabled: false
2.2 全局過(guò)濾器查看
要查看應(yīng)用于路由的全局過(guò)濾器,通過(guò)接口/actuator/gateway/globalfilters以 GET方式請(qǐng)求。示例如下:
{
"org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@1d1deb11": 2147483646,
"org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@221961af": 10150,
"org.springframework.cloud.gateway.filter.ForwardRoutingFilter@1cfb7450": 2147483647,
"org.springframework.cloud.gateway.filter.RemoveCachedBodyFilter@1e288c76": -2147483648,
"org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@738ed8f5": 10000,
"org.springframework.cloud.gateway.filter.GatewayMetricsFilter@18d1d137": 0,
"com.pack.common.filters.SecondFilter@38874eb5": 0,
"com.pack.gray.loadbalancer.GrayReactiveLoadBalancerClientFilter@76b019c4": 10150,
"org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@41463c56": -2147482648,
"org.springframework.cloud.gateway.filter.LoadBalancerServiceInstanceCookieFilter@32ddcca": 10151,
"org.springframework.cloud.gateway.filter.NettyRoutingFilter@1ddc8fc": 2147483647,
"com.pack.common.filters.BrushProofFilter@55202ba6": -2,
"org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@77d58f3a": -1,
"com.pack.common.filters.FirstFilter@2ef1fc8a": 1,
"org.springframework.cloud.gateway.filter.ForwardPathFilter@478c84aa": 0
}
每一個(gè)過(guò)濾器后的數(shù)字是該過(guò)濾器的執(zhí)行順序,值越小,越先執(zhí)行。
2.3 路由過(guò)濾器
要獲取應(yīng)用在路由上的GatewayFilter工廠,通過(guò)接口/actuator/gateway/routefilters 以GET方式請(qǐng)求,示例如下:
圖片
以上包括了系統(tǒng)默認(rèn)的及自定義的網(wǎng)關(guān)過(guò)濾器工廠【CustomGatewayFilterFactory】。
2.4 路由刷新
要清除路由緩存,通過(guò)接口/executor/gateway/refresh 以POST方式請(qǐng)求。該請(qǐng)求返回一個(gè)沒(méi)有響應(yīng)體的200。
圖片
當(dāng)首次訪問(wèn)路由時(shí)會(huì)通過(guò)RouteLocator進(jìn)行路由的查找,而這個(gè)具體實(shí)現(xiàn)是通過(guò)CachingRouteLocator進(jìn)行查找路由,查找到路由以后會(huì)將其緩存在Map集合中。該RouteLocator是個(gè)監(jiān)聽程序,會(huì)監(jiān)聽RefreshRoutesEvent事件,當(dāng)收到該事件后會(huì)重新獲取路由進(jìn)行緩存。
2.5 獲取定義的路由
要獲取網(wǎng)關(guān)中定義的路由,通過(guò)接口/executor/gateway/routes以GET方式請(qǐng)求。
[
{
"predicate": "Paths: [/cloud-gateway/**], match trailing slash: true",
"metadata": {
"nacos.instanceId": null,
"nacos.weight": "1.0",
"nacos.cluster": "DEFAULT",
"nacos.ephemeral": "true",
"nacos.healthy": "true",
"management.port": "8188",
"preserved.register.source": "SPRING_CLOUD"
},
"route_id": "ReactiveCompositeDiscoveryClient_cloud-gateway",
"filters": [
"[[StripPrefix parts = 1], order = 1]",
"[[RewritePath /cloud-gateway/?(?<remaining>.*) = '/${remaining}'], order = 1]"
],
"uri": "lb://cloud-gateway",
"order": 0
},
...
]
字段說(shuō)明:
屬性 | 類型 | 描述 |
route_id | String | 路由id |
route_object.predicate | Object | 路由謂詞 |
route_object.filters | Array | 應(yīng)用于路由的 GatewayFilter 工廠 |
order | Number | 路由順序 |
2.6 獲取特定路由信息
要獲取單個(gè)路由的信息,通過(guò)接口 /actuator/gateway/routes/{id}(例如,/actuator/gateway/routes/first_route)以GET方式請(qǐng)求。示例如下:
圖片
字段說(shuō)明:
屬性 | 類型 | 描述 |
id | String | 路由ID |
predicates | Array | 路由謂詞集合。每項(xiàng)都定義了給定謂詞的名稱和參數(shù) |
filters | Array | 應(yīng)用于路線的過(guò)濾器集合 |
uri | String | 路由的目標(biāo) URI |
order | Number | 路由順序 |
2.7 創(chuàng)建&刪除路由
要?jiǎng)?chuàng)建路由,通過(guò)接口/gateway/routes/{id_route_to_create}以POST方式請(qǐng)求,請(qǐng)求內(nèi)容為指定路由字段的 JSON 格式(請(qǐng)參閱 2.6)。
要?jiǎng)h除路由,通過(guò)接口 /gateway/routes/{id_route_too_delete}以DELETE方式請(qǐng)求。
創(chuàng)建路由
圖片
查詢創(chuàng)建的路由
圖片
注意:默認(rèn)創(chuàng)建的路由是存儲(chǔ)在內(nèi)存中的,重啟服務(wù)后就沒(méi)有了。
刪除路由
2.8 路由共享
Spring Cloud Gateway 提供兩種 RouteDefinitionRepository 實(shí)現(xiàn)。第一種是 InMemoryRouteDefinitionRepository,它只存在于一個(gè)網(wǎng)關(guān)實(shí)例的內(nèi)存中。這種類型的存儲(chǔ)庫(kù)不適合在多個(gè)網(wǎng)關(guān)實(shí)例中填充路由。
為了在 Spring Cloud Gateway 實(shí)例集群中共享路由,可以使用 RedisRouteDefinitionRepository。要啟用此類存儲(chǔ)庫(kù),必須將以下屬性設(shè)置為 true:spring.cloud.gateway.redis-route-definition-repository.enabled 與 RedisRateLimiter 篩選器工廠一樣,它也需要使用 spring-boot-starter-data-redis-reactive 。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
開啟Redis存儲(chǔ)功能
spring:
cloud:
gateway:
redis-route-definition-repository:
enabled: true