• SpringCloud-微服务-Gateway网关配置


    Spring Cloud Gateway 官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-starter

    一、Gateway 网关的作用

    网关主要有以下功能:

    • 身份认证与权限校验
    • 服务路由与负载均衡
    • 请求限流

    用户访问服务流程:

    向网关发起请求 —> 网关对请求路径查找匹配的服务 —> 网关对请求进行校验或过滤处理 —> 网关将请求路由到指定服务 —> 服务返回响应给网关 —> 网关将服务响应返回给客户端

    SpringCloud 中同类的网关服务还有 zuul,但 zuul 基于 Servlet 实现,属于阻塞式编程。

    Gateway 基于 Spring5 中提供的 WebFlux 属于响应式编程,性能更优。

    二、Gateway 快速入门

    1. 依赖与启动类

    Gateway 服务最后也同时使用服务注册中心,以此实现负载均衡,这里选择阿里的 Nacos

    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-gatewayartifactId>
    dependency>
    
    <dependency>
        <groupId>com.alibaba.cloudgroupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    只需上面两个依赖即可,spring-cloud-starter-gateway 中包含 spring-web 相关的依赖,可以直接启动服务

    启动类不需要特别的配置,示例如下:

    @SpringBootApplication
    public class GatewayApplication {
        public static void main(String[] args) {
            SpringApplication.run(GatewayApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2. yaml 基本配置

    application.yml 配置文件示例如下:

    server:
      port: 8088	# 服务端口
    spring:
      application:
        name: gateway	# 服务名称
      cloud:
        nacos:
          server-addr: localhost:8848	# nacos 注册中心地址
        gateway:
          routes:	# 服务路由列表
            # - 表示列表,同级的 - 添加在同一列表内,id, uri, predicates 组成一个路由,是列表内的一个元素
            - id: user-service-route	# 路由 id,不可重复
              # uri 为目标地址,有两个表示方法
              # uri: http://localhost:8082	# 指定固定 ip,无负载均衡
              uri: lb://user-service	# 指定注册中心的服务名称,通过负载均衡发送请求
              predicates:	# 断言规则
                - Path=/user/**	# 匹配以 /user 为开头的请求路径,将其路由到 user-service
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    现在已经可以启动网关服务了,前提是要先启动 Nacos

    启动网关后,客户端访问网关即可,如 localhost:8088/user/1,网关会匹配到 user-service 路由,并将请求路由到从 Nacos 注册中心得到的 user-service 服务

    三、路由断言工厂

    predicates 即为断言,用来判断当前请求是否与服务得路由规则匹配

    有多个断言规则存在时,必须全部符合规则,请求才会被路由转发

    在上面得例子中用到了 - Path,表示对请求路径进行判断

    其它常用的断言工厂如下:
    在这里插入图片描述来自黑马程序员 ppt 截图 ↑

    Gateway 断言工厂官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

    四、负载均衡策略

    服务路由 uri 使用 lb 开头即启用负载均衡,负载均衡策略可以通过 Ribbon来配置

    service-name.ribbon.NFLoadBalancerRuleClassName 配置负载均衡策略,其中 service-name 为 uri 中的服务名称

    默认策略为轮询访问

    spring:
      cloud:
        gateway:
          routes:
            - id: user-service-route
              uri: lb://user-service	# lb 表示负载均衡,后跟服务名称
              predicates:
                - Path=/user/**
    
    # 通过 Ribbon 配置某一服务的负载均衡策略
    user-service:	# 服务名称
      ribbon:
        #    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule	# 随机访问策略
        NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule	# Nacos优先选择策略
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    五、过滤器

    1. 路由过滤器

    路由过滤器是在路由中配置的过滤器,只会对当前路由生效

    在路由配置中添加 filters 属性即可

    示例如下:

    spring:
      cloud:
        gateway:
          routes:
            - id: user-service-route
              uri: lb://user-service
              predicates:
                - Path=/user/**
              filters:	# 添加路由过滤器
                - AddRequestHeader=from, gateway	# 添加请求头 from=gateway
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如上例使用了 - AddRequestHeader 用来给请求添加请求头

    类似的常用的还有:

    • AddRequestHeader:添加请求头
    • RemoveRequestHeader:移除请求头
    • AddRequestParameter:添加查询参数
    • RemoveRequestParameter:移除查询参数
    • AddResponseHeader:添加响应头
    • RemoveRequestParameter:移除响应头

    更多查看 GatewayFilter Factories 官方文档:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

    2. defaultFilter 过滤器

    default 过滤器对所有路由生效

    配置 spring.cloud.gateway.default-filters

    示例如下:

    spring:
      cloud:
        gateway:
          default-filters:
            - AddRequestParameter=message, Hello	# 添加请求参数 message=Hello
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3. 全局过滤器

    新建一个类实现 GlobalFilter 接口中的 filter 方法

    并在类上注解 @Component 将类添加到 Spring 容器即可

    filter 方法中的 exchange 参数表示上下文,其中可以获取 request, response, session 等信息

    chain 参数表示过滤器链,可以进行放行操作

    如下示例实现了简单的权限校验,检验请求头中是否携带了代表有权限的属性:

    @Component
    public class AuthorizeFilter implements GlobalFilter {
    
        private static String adminAuth = "adminAuth";
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 获取请求头中的 Authorization 属性值
            HttpHeaders headers = exchange.getRequest().getHeaders();
            String authorization = headers.getFirst("Authorization");
    
            if (!adminAuth.equals(authorization)) {
                // 设置 401 响应状态码
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                // 完成响应,不再往后进行
                return exchange.getResponse().setComplete();
            }
            // 放行
            return chain.filter(exchange);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在全局过滤器上注解 @Order 注解可以设置过滤器的优先级,用于排列多个过滤器时的顺序

    也可以实现 Ordered 接口中的 getOrder() 方法实现同样的效果

    //@Order(1)	// 注解设置 order 为 1
    @Component
    public class MyFilter implements GlobalFilter, Ordered {
    
        @Override
        public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            return chain.filter(exchange);
        }
    
        @Override
        public int getOrder() {	// 实现方法设置 order 为 1
            return 1;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    4. 过滤器执行顺序

    每一个过滤器都有一个 int 类型 order 值

    过滤器的执行顺序按照 order 值进行排序的,order 值越小优先级越高,越先执行

    全局过滤器的 order 由自己指定,路由过滤器与 defaultFilter 的 order 根据声明顺序由 1 开始递增

    路由过滤器与 defaultFilter 的 order 值是独立分开的

    当三种过滤器的 order 值相同时,有优先级:路由过滤器 > defaultFilter > 全局过滤器

    六、跨域配置

    yaml 配置示例如下:

    spring:
      cloud:
        gateway:
          globalcors: # 全局跨域处理
            add-to-simple-url-handler-mapping: true # 解决 options 请求被拦截问题
            cors-configurations:
              '[/**]':
                allowedOrigins: # 允许哪些网站的跨域请求
                  - "http://localhost:8080"
                allowedMethods: # 允许的跨域请求方法
                  - "GET"
                  - "POST"
                  - "DELETE"
                  - "PUT"
                  - "OPTIONS"
                allowedHeaders: "*" # 允许跨域请求中携带的请求头:全部
                allowCredentials: true  # 是否允许携带 cookie
                maxAge: 360000  # 跨域检测的有效期
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  • 相关阅读:
    Web Components从技术解析到生态应用个人心得指北
    pytorch 配置deformabledetr和referformer工程环境踩坑
    总结一下前后端分离业务流程
    Java之流程控制(5)
    iOS桌面小插件 Widget Extension
    Docker实践笔记6:PHP容器制作
    JZ63 买卖股票的最好时机(一)
    一些思考:腾讯股价为何持续都低
    [SQL开发笔记]SELECT DISTINCT语句:返回唯一不同的值
    Redis与数据库的爱恨纠葛
  • 原文地址:https://blog.csdn.net/Cey_Tao/article/details/127659591