Springcloud-Gateway網關
官網:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html
一.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>
gateway不能導入spring-boot-starter-web依賴,否則會報如下錯誤org.springframework.http.codec.ServerCodecConfigurer‘ that could not be found,因為spring cloud gateway是基於webflux的,如果非要web支持的話需要導入spring-boot-starter-webflux而不是spring-boot-start-web。
-
添加配置
eureka: client: register-with-eureka: true fetch-registry: true service-url: defaultZone: http://localhost:7001/eureka #需要將網關注入到注冊中心 spring: cloud: gateway: enabled: true routes: - id: payment_routh uri: CLOUD-PAYMENT-SERVICE predicates: - Path=/payment/**
-
驗證
payment服務提供者自測: http://localhost:8001/payment/1
通過gateway網關訪問payment服務 http://localhost:7529/payment/1
二. 網關動態路由
之前我們做負載均衡的時候,是通過Ribbon進行,但是現在我們對8001和8002做了網關,那么就需要通過geteway的動態路由實現調用服務
修改application.yml配置文件
spring:
cloud:
gateway:
enabled: true
discovery:
locator:
enabled: true #開啟從注冊中心動態創建路由的功能,利用微服務名進行路由
routes:
- id: payment_routh
uri: lb://CLOUD-PAYMENT-SERVICE #uri的協議為lb,表示啟用gateway網關的負載均衡功能
predicates:
- Path=/payment/**
注意:uri 需要使用lb://不然不會開啟負載均衡的功能
三.Gateway常用的predicates
從官方文檔可以看到predicate有11種,具體的見官方文檔
四.Gateway的Filter過濾器
路由過濾器允許以某種方式修改傳入的 HTTP 請求或傳出的 HTTP 響應。路由過濾器的范圍是特定的路由。Spring Cloud Gateway 包含31種內置的 GatewayFilter ,具體的詳見官方文檔:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
最重要的是使用自定義全局GlobalFilter
- 兩個重要的接口
- GlobalFilter
- Ordered
- 作用
- 全局日志記錄
- 統一網關鑒權
- .....
創建一個全局的gatewayFilter類並實現接口GlobalFilter和Ordered
@Component
@Slf4j
public class MyLogGatewayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("*************come in MyLogGatewayFilter ");
String userName = exchange.getRequest().getQueryParams().getFirst("userName");
if(userName == null)
{
log.info("用戶名為null,非法用戶");
exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}
測試:
有userName的參數進行測試