目錄:
- 1.Gateway 是什麼?
- 2.Gateway 主要能幹什麼?
- 3.Gateway三大核心概念
- 4.Gateway工作流程
- 5.使用執行個體
- 6.Gateway常用Predicate
-
- Ⅰ.After Route Predicate
- Ⅱ.Before Route Predicate
- Ⅲ.Between Route Predicate
- Ⅳ.Cookie Route Predicate
- Ⅴ.Header Route Predicate
- Ⅵ.Host Route Predicate
- Ⅶ.Method Route Predicate
- Ⅷ.Path Route Predicate
- Ⅸ.Query Route Predicate
- 7.Gateway自定義過濾器
1.Gateway 是什麼?
Spring Cloud Gateway是基于Spring Boot 2.x,Spring WebFlux和Project Reactor建構的。Gateway易在提供一種簡單而有效的方式來對API進行路由,以及提供一些強大的過濾功能,例如:熔斷,限流,重試等。
Spring Cloud Gateway作為springcloud生态系統中的網關,目标的替代Zuul,在springcloud 2.0 以上的版本中,沒有對Zuul 2.0 以上版本進行內建,仍然使用Zuul 1.x版本的非Reactor模式的老版本。為了提高網關的性能,Spring Cloud Gateway是基于WebFlux架構實作的,而WebFlux架構底層是使用了高性能的Reactor模式通信架構Netty。
Spring Cloud Gateway需要Spring Boot和Spring Webflux提供的Netty運作時。它不能在傳統的Servlet容器中或作為WAR建構時使用
2.Gateway 主要能幹什麼?
- 反向代理
- 鑒權
- 流量控制
- 熔斷
- 日志監控
3.Gateway三大核心概念
Routr(路由):
網關的基本構模組化塊。它由ID,目标URI,一系列斷言和過濾器集合定義。如果斷言為true,則比對路由。
Predicate(斷言):
參考Java 8 的java.util.function.Predicate。我們可以比對HTTP請求中的所有内容,例如請求頭或參數。如果請求與斷言相比對則進行路由。
Filter(過濾器):
Spring架構中GatewayFilter的執行個體。可以在請求被路由之前或之後對請求進行修改。
4.Gateway工作流程
用戶端向Spring Cloud Gateway送出請求。然後在Gateway Handler Mapping中找到與請求相比對的路由,将其發送到Gateway Web Handdler。Gateway Web Handdler再根據指定的過濾器鍊來将請求發送到我們實際的服務執行業務邏輯,然後傳回。過濾器之間用虛線分開,是因為過濾器可能會在發送代理請求之前或之後,執行業務邏輯。Filter在發送代理請求之前可以做參數校驗,權限校驗,流量監控,日志輸出,協定轉換等,Filter在發送代理請求之後可以做響應内容,響應頭的修改,日志的輸出,流量的監控等。
5.使用執行個體
Ⅰ.在父工程下,建立Module : cloud-gateway-gateway9527
Ⅱ.引入相關依賴:
<dependencies>
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--eureka-client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--引入自己定義的api通用包,可以使用Payment支付Entity-->
<dependency>
<groupId>com.mk</groupId>
<artifactId>cloud-api-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Ⅲ.application.yml 配置檔案
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
- id: payment_route # id 保證唯一性
uri: lb://CLOUD-PROVIDER-SERVICE #比對後提供服務的路由位址
predicates:
- Path=/payment/getServer/** #斷言 路徑相比對進行路由
discovery:
locator:
enabled: true #開啟從注冊中心動态建立路由的功能,利用微服務名進行路由
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://eureka7001.com:7001/eureka
Ⅳ.主啟動類
@SpringBootApplication
@EnableEurekaClient
public class Gateway9527 {
public static void main(String[] args) {
SpringApplication.run(Gateway9527.class,args);
}
}
通路的getServer方法如下:
@GetMapping("/payment/getServer")
public String getServer(){
return this.serverPort;
}
測試結果:
6.Gateway常用Predicate
Ⅰ.After Route Predicate
After Route Predicate有一個參數為datetime(其是Java8 ZonedDateTime)。該謂詞比對在指定日期時間之後發生的請求。
例如如下配置:
spring:
cloud:
gateway:
routes:
- id: payment_route # id 保證唯一性
uri: lb://CLOUD-PROVIDER-SERVICE #比對後提供服務的路由位址
predicates:
- After=2021-05-24T11:22:43.136+08:00[Asia/Shanghai]
2021-05-24 11:22 之後的請求都能夠通路,這個時間之前通路會404
Ⅱ.Before Route Predicate
Before Route Predicate有一個參數為datetime(其是Java8 ZonedDateTime)。該謂詞比對在指定日期時間之前發生的請求。
例如如下配置:
spring:
cloud:
gateway:
routes:
- id: payment_route # id 保證唯一性
uri: lb://CLOUD-PROVIDER-SERVICE #比對後提供服務的路由位址
predicates:
- Before=2021-05-24T11:22:43.136+08:00[Asia/Shanghai]
2021-05-24 11:22 之前的請求都能夠通路,這個時間之後通路會404
Ⅲ.Between Route Predicate
Between Route Predicate有兩個參數,datetime1和datetime2 (其是Java8 ZonedDateTime)。該謂詞比對在該時間段發生的請求。
例如如下配置:
spring:
cloud:
gateway:
routes:
- id: payment_route # id 保證唯一性
uri: lb://CLOUD-PROVIDER-SERVICE #比對後提供服務的路由位址
predicates:
- Between=2021-03-24T11:22:43.136+08:00[Asia/Shanghai], 2021-05-24T11:22:43.136+08:00[Asia/Shanghai]
2021-03-24 11:22 到2021-05-24 11:22之間的請求都能夠通路,不在這個時間段内通路會404
Ⅳ.Cookie Route Predicate
Cookie Route Predicate 需要兩個參數,一個是 Cookie name , 一個是正規表達式,路由規則會通過擷取對應的 Cookie name 值和正規表達式去比對,如果比對上就會執行路由,如果沒有比對上則不執行。
例如如下配置:
spring:
cloud:
gateway:
routes:
- id: payment_route # id 保證唯一性
uri: lb://CLOUD-PROVIDER-SERVICE #比對後提供服務的路由位址
predicates:
- Cookie=username, thh
curl 測試
不攜帶Cookie
攜帶Cookie
Ⅴ.Header Route Predicate
Header Route Predicate 需要兩個參數,報頭name和一個regexp(其是Java正規表達式)。該謂詞與具有給定名稱的标頭比對,該标頭的值與正規表達式比對。
例如如下配置:
spring:
cloud:
gateway:
routes:
- id: payment_route # id 保證唯一性
uri: lb://CLOUD-PROVIDER-SERVICE #比對後提供服務的路由位址
predicates:
- Header=X-Request-Id, \d+
curl測試:
curl http://localhost:9527/payment/getServer -H "X-Request-Id:123"比對成功
curl http://localhost:9527/payment/getServer -H "X-Request-Id:hello"會出現404
Ⅵ.Host Route Predicate
Host Route Predicate需要一個參數:主機名的清單patterns。該模式是帶有.分隔符的Ant樣式的模式。謂詞與Host比對模式的标頭比對。
例如如下配置:
spring:
cloud:
gateway:
routes:
- id: payment_route # id 保證唯一性
uri: lb://CLOUD-PROVIDER-SERVICE #比對後提供服務的路由位址
predicates:
- Host=**.somehost.org
curl測試:
curl http://localhost:9527/payment/getServer -H "Host:www.somehost.org"比對成功
curl http://localhost:9527/payment/getServer 會出現404
Ⅶ.Method Route Predicate
Method Route Predicate需要methods的參數,它是一個或多個參數:HTTP方法來比對。
例如如下配置:
spring:
cloud:
gateway:
routes:
- id: payment_route # id 保證唯一性
uri: lb://CLOUD-PROVIDER-SERVICE #比對後提供服務的路由位址
predicates:
- Method=GET,POST
方法是GET,POST允許通路,否則404
Ⅷ.Path Route Predicate
Path Route Predicate 接收一個比對路徑的參數來判斷是否走路由。
例如如下配置:
spring:
cloud:
gateway:
routes:
- id: payment_route # id 保證唯一性
uri: lb://CLOUD-PROVIDER-SERVICE #比對後提供服務的路由位址
predicates:
- Path=/payment/getServer/**
curl http://localhost:9527/payment/getServer/1 通路成功
curl http://localhost:9527/payment/getServer/xx 通路成功
curl http://localhost:9527/payment/aa/xx 通路失敗
Ⅸ.Query Route Predicate
Query Route Predicate 支援傳入兩個參數,一個是屬性名一個為屬性值,屬性值可以是正規表達式。
例如如下配置:
spring:
cloud:
gateway:
routes:
- id: payment_route # id 保證唯一性
uri: lb://CLOUD-PROVIDER-SERVICE #比對後提供服務的路由位址
predicates:
- Query=username, \d+
curl http://localhost:9527/payment/getServer?username=1 通路成功
curl http://localhost:9527/payment/getServer?username=-1 通路失敗
以上這些可以組合使用 如:
spring:
cloud:
gateway:
routes:
- id: payment_route # id 保證唯一性
uri: lb://CLOUD-PROVIDER-SERVICE #比對後提供服務的路由位址
predicates:
- Query=username, \d+
- Path=/payment/getServer/** #斷言 路徑相比對進行路由
- Before=2021-05-24T11:22:43.136+08:00[Asia/Shanghai]
7.Gateway自定義過濾器
内置過濾器:移步官網,主要是太多了,不是我懶(T_T),主要掌握下自定義過濾器。
實作自定義的Gateway Filter,需要GatewayFilter、Ordered兩個接口
@Component
@Slf4j
public class MyLogGatewayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("*****************come in MyLogGatewayFilter"+new Date());
String uname = exchange.getRequest().getQueryParams().getFirst("uname");
if(StringUtils.isEmpty(uname)){
log.info("非法使用者");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
測試 案例比較簡單,就是判斷下是否攜帶uname這個參數
寫作不易,加個關注呗
求關注、求點贊!