SpringCloud Gateway
SpringCloud Gateway是Spring Cloud的一個全新項目,基于Spring5.0 + Spring Boot2.0和Project Reactor等技術開發的網關,它的宗旨是在為微服務架構提供一種簡單有效的統一的API路由管理方式。
SpringCloud Gateway作為Spring Cloud生态系統中的網關,目标是替代Zuul,在Sptring Cloud2.0以上版本中,沒有對新版本的Zuul2.0以上最新高性能版本進行內建,仍然還是使用Zuul1.0非Reactor模式的老版本。而為了提升網關的性能,SpringCloud Gateway是基于WebFlux架構實作的,而WebFlux架構底層則使用了高性能的Reactor模式通信架構Netty。
Gateway三大核心概念
- 路由:路由時候建構網關的基本子產品,它由ID,目标URI,一系列的斷言和過濾組成,如果斷言為true則比對該路由
- 斷言:開發人員可以1比對HTTP請求的所有内容,如果請求與斷言比對則進行路由
- 過濾:指的是Spring架構中GatewayFilter的執行個體,使用過濾器,可以在請求被路由前或者之後對請求進行修改
Gateway工作流程

用戶端向Spring Cloud Gateway送出請求。然後再Gateway Handler Mapping 中找到與請求相比對的路由,将其發送到Gateway Web Handler。Handler再通過制定的過濾器鍊來将請求發送到我們實際的服務執行業務邏輯。
Gateway網關的使用
- SpringBoot項目添加maven依賴
<!-- gateway --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
- 配置檔案添加網關路由配置
server: port: 9527 spring: application: name: cloud-gateway cloud: gateway: routes: - id: payment_route #路由id,自定義唯一值 uri: http://localhost:8001 #真實提供服務的位址 predicates: - Path=/payment/get/** #斷言:路徑相比對的進行路由 - id: payment_route2 uri: http://locahost:8001 predicates: - Path=/payment/delete/** #eureka client eureka: instance: hostname: cloud-gateway-service client: service-url: register-with-eureka: true fetch-registry: true defaultZone: http://eureka1.com:7001/eureka/
- 啟動類
@SpringBootApplication @EnableEurekaClient public class GatewayApplication { public static void main(String[] args) { SpringApplication.run(GatewayApplication.class,args); } }
- 請求測試,通過網關通路實際接口
SpringCloud服務網關GatewaySpringCloud GatewayGateway三大核心概念Gateway工作流程Gateway網關的使用通過Java代碼配置網關通過微服務名稱實作動态路由Predicates規則過濾器(Filter)
通過Java代碼配置網關
可以不用上面配置檔案的方法配置網關,直接在Spring中注入RouteLocator,通過Java代碼實作網關路由配置
@Configuration
public class GatewayConfig {
/**
* spring中注入bean RouteLocator
* @param builder
* @return
*/
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder){
RouteLocatorBuilder.Builder routes = builder.routes();
//路由配置
routes.route("payment_route",r -> r.path("/payment/get/**").uri("http://localhost:8001")).build();
routes.route("paymemt_route1", r -> r.path("/payment/delete/**").uri("http://localhost:8001")).build();
return routes.build();
}
}
通過微服務名稱實作動态路由
Gateway注冊進服務注冊中心。配置檔案開啟動态建立路由,服務通路位址換成微服務名稱
server:
port: 9527
spring:
application:
name: cloud-gateway
cloud:
gateway:
routes:
- id: payment_route
uri: lb://cloud-payment-service # 提供服務的路由位址 lb://{服務名稱}
predicates:
- Path=/payment/get/**
discovery:
locator:
enabled: true #開啟從注冊中心動态建立路由功能,利用微服務名稱進行路由
#eureka client
eureka:
instance:
hostname: cloud-gateway-service
client:
service-url:
register-with-eureka: true
fetch-registry: true
defaultZone: http://eureka1.com:7001/eureka/
Predicates規則
predicates:
- Path=/payment/get/** #服務位址
- After=2021-03-22T20:38:31.461+08:00[Asia/Shanghai] #在這個時間之後才能通路
- Before=2021-03-22T25:38:31.461+08:00[Asia/Shanghai] #在這個時間之前才能通路
- Cookie=[cookiename],[正規表達式] #cookie裡對應的cookiename符合正規表達式才可以通路
- Header=[headername],[正規表達式] #請求頭裡對應的name符合正則才可以通路
- Method=GET #隻允許get方法請求
- Query=[paramName],[正規表達式] #參數paramName的值必須符合正則才可以通路,比如 price,[1-9]\d+(.\d{1,2})?,參數price必須是大于0的金額才能通路
- Host=**.baidu.com #符合的host才可以通路
過濾器(Filter)
路由過濾器可用于修改進入的HTTP請求和傳回HTTP響應(跟web.xml配置的過濾器一樣)。Spring Cloud Gateway内置了多種路由過濾器,他們都由GatewayFilter的工廠類來産生。
自定義過濾器
/**
* 全局自定義過濾器
* 繼承GlobalFilter,Ordered
*/
@Component
public class MyFilter implements GlobalFilter,Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//擷取參數
String username = exchange.getRequest().getQueryParams().getFirst("username");
if(username == null){
System.out.println("======非法請求======");
exchange.getResponse().setStatusCode(HttpStatus.NOT_FOUND);
//攔截請求直接傳回
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
/**
* 加載過濾器的順序,越小優先級越高
* @return
*/
@Override
public int getOrder() {
return 0;
}
}