SpringCloud-Gateway 使用记录

3 minute

网关的作用

如图所示,网关介于外部请求和具体微服务之间,在不暴露内部微服务端口的情况下,通过一个或者多个指定的网关端口统一地处理外部各种请求。

使用 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,负载均衡功能也测试成功。