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