javascript
Spring Cloud GatewayAPI网关服务
一、Gateway 簡介
Gateway是在Spring生態(tài)系統(tǒng)之上構(gòu)建的API網(wǎng)關(guān)服務(wù),基于Spring 5,Spring Boot 2和 Project Reactor等技術(shù)。Gateway旨在提供一種簡單而有效的方式來對API進行路由,以及提供一些強大的過濾器功能, 例如:熔斷、限流、重試等。
Spring Cloud Gateway 具有如下特性:
- 基于Spring Framework 5, Project Reactor 和 Spring Boot 2.0 進行構(gòu)建;
- 動態(tài)路由:能夠匹配任何請求屬性;
- 可以對路由指定 Predicate(斷言)和 Filter(過濾器);
- 集成Hystrix的斷路器功能;
- 集成 Spring Cloud 服務(wù)發(fā)現(xiàn)功能;
- 易于編寫的 Predicate(斷言)和 Filter(過濾器);
- 請求限流功能;
- 支持路徑重寫。
二、相關(guān)概念
- Route(路由):路由是構(gòu)建網(wǎng)關(guān)的基本模塊,它由ID,目標URI,一系列的斷言和過濾器組成,如果斷言為true則匹配該路由;
- Predicate(斷言):指的是Java 8 的 Function Predicate。
輸入類型是Spring框架中的ServerWebExchange。
這使開發(fā)人員可以匹配HTTP請求中的所有內(nèi)容,例如請求頭或請求參數(shù)。如果請求與斷言相匹配,則進行路由; - Filter(過濾器):指的是Spring框架中GatewayFilter的實例,使用過濾器,可以在請求被路由前后對請求進行修改。
三、創(chuàng)建gateway模塊
這里我們創(chuàng)建一個api-gateway模塊來演示Gateway的常用功能。
在pom.xml中添加相關(guān)依賴
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency>Gateway 提供了兩種不同的方式用于配置路由,
- 一種是通過yml文件來配置,
- 另一種是通過Java Bean來配置
- 使用yml配置
在application.yml中進行配置:
server:port: 2007 spring:cloud:gateway:discovery:locator:enabled: true #開啟從注冊中心動態(tài)創(chuàng)建路由的功能,利用微服務(wù)名進行路由routes:- id: user-service #路由的ID,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名# uri: http://localhost:8008 #匹配后提供服務(wù)的路由地址uri: lb://user-service #匹配后提供服務(wù)的路由地址,進行負載均衡predicates:- Path=/user/** # 斷言,路徑相匹配的進行路由- id: payment_routh2 #payment_route #路由的ID,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名#uri: http://localhost:8001 #匹配后提供服務(wù)的路由地址uri: lb://payment-service #匹配后提供服務(wù)的路由地址predicates:- Path=/payment/lb/** # 斷言,路徑相匹配的進行路由#- After=2021-05-21T15:51:37.485+08:00[Asia/Shanghai]#- Cookie=username,xxxx#- Header=X-Request-Id, \d+ # 請求頭要有X-Request-Id屬性并且值為整數(shù)的正則表達式- java Bean配置方式
添加相關(guān)配置類,并配置一個RouteLocator對象:
四、啟動nacos,user-service和gateway服務(wù)
nacos控制面板:
并調(diào)用該地址測試:http://localhost:2007/user/1
因為我采用了負載均衡策略,所以可以看到,8086的微服務(wù),和8088的微服務(wù)被輪詢訪問
訪問:http://localhost:2007/user/getByUsername?username=andy
五、Route Predicate 的使用
Spring Cloud Gateway將路由匹配作為Spring WebFlux HandlerMapping基礎(chǔ)架構(gòu)的一部分。 Spring Cloud Gateway包括許多內(nèi)置的Route Predicate工廠。 所有這些Predicate都與HTTP請求的不同屬性匹配。 多個Route Predicate工廠可以進行組合,下面我們來介紹下一些常用的Route Predicate。
注意:Predicate中提到的配置都在application-predicate.yml文件中進行修改,并用該配置啟動api-gateway服務(wù)。
使用curl工具發(fā)送帶有cookie為username=macro的請求可以匹配該路由。
curl http://localhost:9201/user/1 --cookie "username=macro"使用curl工具發(fā)送帶有請求頭為X-Request-Id:123的請求可以匹配該路由。
curl http://localhost:9201/user/1 -H "X-Request-Id:123"帶有指定Host的請求會匹配該路由。
使用curl工具發(fā)送帶有請求頭為Host:www.xxxxx.com的請求可以匹配該路由。
curl http://localhost:9201/user/1 -H "Host:www.xxxxx.com"使用curl工具發(fā)送GET請求可以匹配該路由。
curl http://localhost:9201/user/1使用curl工具發(fā)送POST請求無法匹配該路由。
curl -X POST http://localhost:9201/user/1使用curl工具發(fā)送/user/1路徑請求可以匹配該路由。
curl http://localhost:9201/user/1使用curl工具發(fā)送/abc/1路徑請求無法匹配該路由。
curl http://localhost:9201/abc/1使用curl工具發(fā)送帶username=macro查詢參數(shù)的請求可以匹配該路由。
curl http://localhost:9201/user/getByUsername?username=macro使用curl工具發(fā)送帶不帶查詢參數(shù)的請求無法匹配該路由。
curl http://localhost:9201/user/getByUsername使用curl工具從192.168.1.1發(fā)起請求可以匹配該路由。
curl http://localhost:9201/user/1以下表示有80%的請求會被路由到localhost:8201,20%會被路由到localhost:8202。
六、Route Filter 的使用
路由過濾器可用于修改進入的HTTP請求和返回的HTTP響應(yīng),路由過濾器只能指定路由進行使用。Spring Cloud Gateway 內(nèi)置了多種路由過濾器,他們都由GatewayFilter的工廠類來產(chǎn)生,下面我們介紹下常用路由過濾器的用法。
以上配置會對GET請求添加username=macro的請求參數(shù),通過curl工具使用以下命令進行測試。
curl http://localhost:9201/user/getByUsername相當于發(fā)起該請求:
curl http://localhost:8201/user/getByUsername?username=macro以上配置會把以/user-service/開頭的請求的路徑去除兩位,通過curl工具使用以下命令進行測試。
curl http://localhost:9201/user-service/a/user/1相當于發(fā)起該請求:
curl http://localhost:8201/user/1以上配置會對所有GET請求添加/user路徑前綴,通過curl工具使用以下命令進行測試。
curl http://localhost:9201/1相當于發(fā)起該請求:
curl http://localhost:8201/user/1要開啟斷路器功能,我們需要在pom.xml中添加Hystrix的相關(guān)依賴:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>然后添加相關(guān)服務(wù)降級的處理類:
@RestController public class FallbackController {@GetMapping("/fallback")public Object fallback() {Map<String,Object> result = new HashMap<>();result.put("data",null);result.put("message","Get request fallback!");result.put("code",500);return result;} }在application-filter.yml中添加相關(guān)配置,當路由出錯時會轉(zhuǎn)發(fā)到服務(wù)降級處理的控制器上:
spring:cloud:gateway:routes:- id: hystrix_routeuri: http://localhost:8201predicates:- Method=GETfilters:- name: Hystrixargs:name: fallbackcmdfallbackUri: forward:/fallback關(guān)閉user-service,調(diào)用該地址進行測試:http://localhost:9201/user/1 ,發(fā)現(xiàn)已經(jīng)返回了服務(wù)降級的處理信息。
在pom.xml中添加相關(guān)依賴:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId> </dependency>添加限流策略的配置類,這里有兩種策略一種是根據(jù)請求參數(shù)中的username進行限流,另一種是根據(jù)訪問IP進行限流;
@Configuration public class RedisRateLimiterConfig {@BeanKeyResolver userKeyResolver() {return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("username"));}@Beanpublic KeyResolver ipKeyResolver() {return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());} }我們使用Redis來進行限流,所以需要添加Redis和RequestRateLimiter的配置,這里對所有的GET請求都進行了按IP來限流的操作;
server:port: 9201 spring:redis:host: localhostpassword: 123456port: 6379cloud:gateway:routes:- id: requestratelimiter_routeuri: http://localhost:8201filters:- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 1 #每秒允許處理的請求數(shù)量redis-rate-limiter.burstCapacity: 2 #每秒最大處理的請求數(shù)量key-resolver: "#{@ipKeyResolver}" #限流策略,對應(yīng)策略的Beanpredicates:- Method=GET logging:level:org.springframework.cloud.gateway: debug多次請求該地址:http://localhost:9201/user/1 ,會返回狀態(tài)碼為429的錯誤;
修改配置文件:
spring:cloud:gateway:routes:- id: retry_routeuri: http://localhost:8201predicates:- Method=GETfilters:- name: Retryargs:retries: 1 #需要進行重試的次數(shù)statuses: BAD_GATEWAY #返回哪個狀態(tài)碼需要進行重試,返回狀態(tài)碼為5XX進行重試backoff:firstBackoff: 10msmaxBackoff: 50msfactor: 2basedOnPreviousValue: false文章轉(zhuǎn)自
更多關(guān)于gateway的配置
總結(jié)
以上是生活随笔為你收集整理的Spring Cloud GatewayAPI网关服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 一些关于爱情的心理学事实
- 下一篇: 2020年产品经理生存报告