五、搭建springCloudAlibaba2021.1版本分布式微服务-gateway网关

发布时间:2022-07-12 16:30:29 作者:yexindonglai@163.com 阅读(1735)

GateWay

(1)简介

  Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。

  github:https://github.com/apex/gateway

(2)为什么使用Gateway

  Spring Cloud Gateway 可以看做是一个 Zuul 1.x 的升级版和代替品,比 Zuul 2 更早的使用 Netty 实现异步 IO,从而实现了一个简单、比 Zuul 1.x 更高效的、与 Spring Cloud 紧密配合的 API 网关。
  Spring Cloud Gateway 里明确的区分了 Router 和 Filter,并且一个很大的特点是内置了非常多的开箱即用功能,并且都可以通过 SpringBoot 配置或者手工编码链式调用来使用。
比如内置了 10 种 Router,使得我们可以直接配置一下就可以随心所欲的根据 Header、或者 Path、或者 Host、或者 Query 来做路由。
比如区分了一般的 Filter 和全局 Filter,内置了 20 种 Filter 和 9 种全局 Filter,也都可以直接用。当然自定义 Filter 也非常方便。

(3)概念

搭建Spring cloud alibaba gateway

1、pom.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <parent>
  6. <artifactId>spring-cloud-alibaba-2021</artifactId>
  7. <groupId>org.example</groupId>
  8. <version>1.0-SNAPSHOT</version>
  9. </parent>
  10. <modelVersion>4.0.0</modelVersion>
  11. <artifactId>spring-cloud-alibaba-2021-gateway</artifactId>
  12. <dependencies>
  13. <!-- nacos 服务注册发现(客户端)依赖 -->
  14. <dependency>
  15. <groupId>com.alibaba.cloud</groupId>
  16. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  17. </dependency>
  18. <!-- gateway 网关依赖 -->
  19. <dependency>
  20. <groupId>org.springframework.cloud</groupId>
  21. <artifactId>spring-cloud-starter-gateway</artifactId>
  22. </dependency>
  23. <!--spring-cloud-dependencies 2020.0.0 版本不在默认加载bootstrap.yml 文件,如果需要加载bootstrap 文件需要手动添加依赖-->
  24. <dependency>
  25. <groupId>org.springframework.cloud</groupId>
  26. <artifactId>spring-cloud-starter-bootstrap</artifactId>
  27. </dependency>
  28. <!--loadbalancer ,负载均衡,用来替代ribbon的组件 -->
  29. <dependency>
  30. <groupId>org.springframework.cloud</groupId>
  31. <artifactId>spring-cloud-starter-loadbalancer</artifactId>
  32. </dependency>
  33. </dependencies>
  34. </project>
2、父项目添加module

在 parent工程的 pom.xml 文件中加入以下内容

  1. <modules>
  2. <module>spring-cloud-alibaba-2021-gateway</module>
  3. </modules>
3、配置文件

为了方便查看层级关系,这里将配置分为2个:

  • bootstrap.yml:用来存放注册中心配置
  • application.yml:用来存放网关配置

bootstrap.yml 内容如下

  1. spring:
  2. application:
  3. name: gateway-demo
  4. profiles:
  5. active: yexindong_active
  6. cloud:
  7. nacos:
  8. discovery:
  9. server-addr: chn520.cn:8848 # 服务注册中心地址
  10. namespace: public # 注册到nacos的名称空间,默认为public

application.yml 内容如下

  1. # 应用服务 WEB 访问端口
  2. server:
  3. port: 8090
  4. spring:
  5. # 后面的bean会覆盖前面相同名称的bean
  6. main:
  7. allow-bean-definition-overriding: true
  8. cloud:
  9. gateway:
  10. discovery:
  11. locator:
  12. #表示gateway开启服务注册和发现功能,
  13. #并且spring cloud gateway自动根据服务发现为每一个服务创建了一个router,这个router将以服务名开头的请求路径转发到对应的服务
  14. enabled: true
  15. #表示将请求路径的服务名配置改成小写 因为服务注册的时候,向注册中心注册时将服务名转成大写的了
  16. lower-case-service-id: true
  17. # alibaba在2020版之后不使用ribbon,这里使用loadbalancer代替,在配置文件中禁用ribbon
  18. # loadbalander:
  19. # ribbon:
  20. # enable: false
4、gateway 过滤器

创建 GatewayFilter.java 文件,内容如下

  1. package com.alibaba.cloud.filter;
  2. import org.springframework.cloud.gateway.filter.GatewayFilterChain;
  3. import org.springframework.cloud.gateway.filter.GlobalFilter;
  4. import org.springframework.core.Ordered;
  5. import org.springframework.http.HttpStatus;
  6. import org.springframework.http.server.reactive.ServerHttpRequest;
  7. import org.springframework.stereotype.Component;
  8. import org.springframework.web.server.ServerWebExchange;
  9. import reactor.core.publisher.Mono;
  10. /**
  11. * gateway 过滤器
  12. */
  13. @Component
  14. public class GatewayFilter implements GlobalFilter, Ordered {
  15. @Override
  16. public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
  17. System.out.println("进入过滤器...");
  18. // 获取请求对象request
  19. ServerHttpRequest request = exchange.getRequest();
  20. System.out.println("请求url:" + request.getURI().getPath());
  21. return chain.filter(exchange);
  22. }
  23. @Override
  24. public int getOrder() {
  25. return 0;
  26. }
  27. }
5、启动类

创建 GatewayApp.java 文件,内容如下

  1. package com.alibaba.cloud;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
  5. @SpringBootApplication
  6. @EnableDiscoveryClient
  7. public class GatewayApp {
  8. public static void main(String[] args) {
  9. SpringApplication.run(GatewayApp.class, args);
  10. }
  11. }
6、测试

注意: gateway 在默认情况下,会转发所有的服务的请求,前提是这些服务已经注册到nacos/eureka

在浏览器输入地址: http://127.0.0.1:8090/serviceName/order/getOrderList ; 将serviceName 改为你自己的服务名称;网关就会自动访问对应服务的地址;

比如我访问的地址是:http://127.0.0.1:8090/order-demo/order/getOrderList;网关就会自动去访问 order-demo服务地址:http://127.0.0.1:8088/order/getOrderList(order-demo服务的端口为8088); 访问成功了,如下图:

7、配置gateway路由转发策略

7.1、根据路径匹配
application.yml 加入以下内容

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: order_route1 # 路由的唯一标识
  6. # 需要转发的地址,这里直接转发到 nacos 中注册的 order-demo 服务, lb表示使用本地负载均衡策略
  7. uri: lb://order-demo
  8. # 配置断言规则
  9. predicates:
  10. - Path=/o/**
  11. # 过滤器
  12. filters:
  13. - StripPrefix=1 # 转发之前去掉第一层路由,比如请求 /x1/x2/x3,转发后会变成/x2/x3

然后在浏览器访问 :http://127.0.0.1:8090/o/order/getOrderList 就会自动转发到 order-demo服务的http://127.0.0.1:8088/order/getOrderList(order-demo服务的端口为8088);访问成功了,如下图:

除此之外,gateway还有其他的转发规则
7.2、时间点后匹配

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: after_route
  6. uri: https://example.org
  7. predicates:
  8. - After=2022-02-20T17:42:47.789-07:00[America/Denver]

7.3、时间点前匹配

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: before_route
  6. uri: https://example.org
  7. predicates:
  8. - Before=2022-02-20T17:42:47.789-07:00[America/Denver]

7.4、时间区间匹配

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: between_route
  6. uri: https://example.org
  7. predicates:
  8. - Between=2022-01-20T17:42:47.789-07:00[America/Denver],
  9. 2022-01-21T17:42:47.789-07:00[America/Denver]

7.5、指定Cookie正则匹配指定值

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: cookie_route
  6. uri: https://example.org
  7. predicates:
  8. - Cookie=cookie,china

7.6、指定Header正则匹配指定值

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: header_route
  6. uri: https://example.org
  7. predicates:
  8. - Header=X-Request-Id

7.7、请求Host匹配指定值

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: host_route
  6. uri: https://example.org
  7. predicates:
  8. - Host=**.somehost.org,**.anotherhost.org

7.8、请求Method匹配指定请求方式

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: method_route
  6. uri: https://example.org
  7. predicates:
  8. - Method=GET,POST

7.9、请求路径正则匹配

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: path_route
  6. uri: https://example.org
  7. predicates:
  8. - Path=/red/{segment},/blue/{segment}

7.10、请求包含某参数

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: query_route
  6. uri: https://example.org
  7. predicates:
  8. - Query=green

7.11、请求包含某参数并且参数值匹配正则表达式

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: query_route
  6. uri: https://example.org
  7. predicates:
  8. - Query=red, gree.

7.12、远程地址匹配

  1. spring:
  2. cloud:
  3. gateway:
  4. routes:
  5. - id: remoteaddr_route
  6. uri: https://example.org
  7. predicates:
  8. - RemoteAddr=192.168.1.1/24

关键字SpringCloud