SpringCloud-Gateway 使用记录
网关的作用
如图所示,网关介于外部请求和具体微服务之间,在不暴露内部微服务端口的情况下,通过一个或者多个指定的网关端口统一地处理外部各种请求。
使用 SpringCloud Gateway
依赖引入
除了基本依赖以外,引入下列依赖:
1<!-- others -->
2<dependency>
3 <groupId>org.springframework.cloud</groupId>
4 <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
5</dependency>
6<dependency>
7 <groupId>org.springframework.cloud</groupId>
8 <artifactId>spring-cloud-starter-gateway</artifactId>
9</dependency>
注意不能引入 web 相关依赖,因为 Gateway 是基于 WebFlux 的。
文件配置
列出部分重要配置:
1server:
2port: 9669
3cloud:
4 gateway:
5 discovery:
6 locator:
7 enabled: true # 开启从注册中心动态创建路由的功能,利用微服务名进行路由
8 routes:
9 - id: path_route
10 uri: lb://CLOUD-PAYMENT-SERVICE # lb:负载均衡
11 predicates:
12 - Path=/payment/**
13 - After=2022-07-26T17:33:52.449+08:00[Asia/Shanghai] # ZonedDateTime.now()
14 - Cookie=username,jzh
注意点如下:
- 9669 端口作为网关端口;
- uri 中 http 改为了 lb,用于负载均衡;
- predicates,即断言,上述断言为:
- 匹配路径:/payment/**;
- 开始允许访问时间:
ZonedDateTime.now()
(Java函数获取该格式时间) - 携带cookie:
key=username, value=jzh
过滤器配置
实现 GlobalFilter, Ordered,重写方法即可:
1@Component
2@Slf4j
3public class MyGlobalFilter implements GlobalFilter, Ordered {
4 @Override
5 public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
6 String username = exchange.getRequest().getQueryParams().getFirst("username");
7 if (username == null) {
8 log.info("username lost");
9 exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
10 return exchange.getResponse().setComplete();
11 }
12 return chain.filter(exchange);
13 }
14
15 @Override
16 public int getOrder() {
17 return 0;
18 }
19}
定义了 url 中携带必须携带一个 key 为 username 的参数。
测试
注意先开启指定的微服务,访问http://localhost:9669/payment/get/11?username=aaa
(同时配好cookie),成功返回结果:
1{
2 "code": 200,
3 "data": {
4 "serial": "8asd8sa2j",
5 "id": 11
6 },
7 "message": "查询成功,访问端口:8001"
8}
再刷新,发现端口动态变化为8002,负载均衡功能也测试成功。