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的参数进行测试