Spring Cloud 之 Gateway 网关

2023年 7月 19日 60.2k 0

🍓 简介:java系列技术分享(👉持续更新中...🔥)
🍓 初衷:一起学习、一起进步、坚持不懈
🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏
🍓 希望这篇文章对你有所帮助,欢迎点赞 👍 收藏 ⭐留言 📝

一、Gateway简介

Gateway官网:spring.io/projects/sp…
Spirng Cloud 中网关的实现包括两种:

  • gateway
  • zuul
  • zuul是基于Servlet的实现,属于阻塞式编程,而Spring Cloud Gateway 则是基于Spring 5 中提供的WebFlux,属于响应式编程的实现,具备更好的性能。

    Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。Spring Cloud Gateway作为Spring Cloud生态系中的网关,目标是替代Netflix ZUUL,其不仅提供统一的路由方式,并且基于Filter链的方式提供了网关基本的功能,例如:身份验证,权限效验,服务路由,负载均衡,请求限流。

    在这里插入图片描述

    二、Spring Cloud Gateway入门案例

    本篇文章将介绍Spring Cloud Alibaba体系下Spring Cloud Gateway的搭建,服务注册中心和分布式配置中心使用Nacos

    2.1 父工程依赖

    
        
            org.springframework.boot
            spring-boot-starter-parent
            2.6.3
            
        
        
    	 
            1.8
            2021.0.1
            2021.0.1.0
         
    
        
            
            
                
                    org.springframework.cloud
                    spring-cloud-dependencies
                    ${spring-cloud.version}
                    pom
                    import
                
                
                
                    com.alibaba.cloud
                    spring-cloud-alibaba-dependencies
                    ${spring-cloud-alibaba.version}
                    pom
                    import
                
            
        
    

    2.2 gateway网关搭建

    2.2.1 pom依赖

        
            
            
                com.alibaba.cloud
                spring-cloud-starter-alibaba-nacos-discovery
            
            
            
                org.springframework.cloud
                spring-cloud-starter-gateway
            
        
    

    2.2.2 yml配置

    server:
      port: 10010 # 网关端口
    spring:
      application:
        name: gateway # 服务名称
      cloud:
        nacos:
          server-addr: localhost:8848 # nacos地址
        gateway:
          routes: # 网关路由配置
            - id: consumer-server # 路由id,自定义,只要唯一即可
    #          uri: http://127.0.0.1:20087 # 路由的目标地址 http就是固定地址
              uri: lb://consumer-server # 路由的目标地址 lb就是负载均衡,后面跟服务名称
              predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
                - Path=/consumer/** # 这个是按照路径匹配,只要以/user/开头就符合要求
                - 
            - id: provider-server
              # uri: http://127.0.0.1:8081
              uri: lb://provider-server 
              predicates: 
                - Path=/provider/** 
    
    • 路由id : 路由的唯一标识
    • 路由目标(uri): 路由的目标地址,http代表固定地址,lb代表根据服务名负载均衡
    • `路由断言(predicates) : 判断路由的规则
    • 路由过滤器filters() : 对请求或响应做处理

    2.2.3 可能存在的问题

    启动报错

    ***************************
    APPLICATION FAILED TO START
    ***************************
    
    Description:
    
    Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway.
    
    Action:
    
    Please set spring.main.web-application-type=reactive or remove spring-boot-starter-web dependency.
    
    Exception in thread "main" java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration$SpringMvcFoundOnClasspathConfiguration': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.gateway.config.GatewayClassPathWarningAutoConfiguration$SpringMvcFoundOnClasspathConfiguration]: Constructor threw exception; nested exception is org.springframework.cloud.gateway.support.MvcFoundOnClasspathException
    
    

    产生原因
    gateway的内部是通过netty+webflux实现的,webflux实现和springmvc配置依赖冲突。

    解决方案:

  • 去除父工程中的 spring-boot-starter-web 这个依赖
  • 或者如下排除
  • 
        org.springframework.cloud
         spring-cloud-starter-gateway
         
             
                 org.springframework.boot
                 spring-boot-starter-web
             
             
                 org.springframework.boot
                 spring-boot-starter-webflux
             
         
    
    
    

    如果uri使用lb负载均衡配置,可能会报错如下:

    启动正常,调用可能会出现,没有可用的服务等信息

    There was an unexpected error (type=Service Unavailable, status=503).
    

    添加如下依赖

            
                org.springframework.cloud
                spring-cloud-starter-loadbalancer
            
    

    2.2.4 调用测试成功

    在这里插入图片描述

    未使用网关
    在这里插入图片描述
    使用网关10010端口调用

    在这里插入图片描述

    三、网关路由流程图

    在这里插入图片描述

    四、Nginx网关和GateWay网关的区别

  • Nignx是流量网关,GateWay是业务网关

  • 流量网关相当于访问的一个总入口,前端页面的一个容器,类似于防火。主要的功能有管理日志,流量监控,黑白名单,请求的负载均衡,全局限流等。

  • 而业务网关是针对具体的后端应用和服务,主要的功能是缓存策略、鉴权策略等

  • 一般流量网关配置在前,业务网关配置在后

  • Nginx是C语言写的,GateWay是java语言写的

  • GateWay主要是路由、断言和过滤器,利用这些可以做流控

  • Nginx主要是负载均衡,反向代理,以及做web服务器

  • 五、路由断言工厂

    官网12种示例地址 : docs.spring.io/spring-clou…

    在这里插入图片描述
    在这里插入图片描述

    六、过滤器工厂

    6.1 GatewayFilter路由过滤器

    官网示例地址 : docs.spring.io/spring-clou…

    GatewayFilter是网关中提供的一种过滤器,可以对进入网关的请求和微服务返回的响应做处理.。

    在这里插入图片描述

    在这里插入图片描述

    6.2 默认过滤器

    要对所有的路由都生效,则可以将过滤器工厂写到defalut下

    spring:
      cloud:
        gateway:
          routes: # 网关路由配置
            - id: consumer-server # 路由id,自定义,只要唯一即可
    #        .....
          default-filters:
            - AddRequestHeader=X-Request-red, blue
    

    6.3 全局过滤器

    全局过滤器,对所有路由生效。通过实现GlobalFilter接口创建

    全局过滤器的作用是处理一切进入网关的请求和微服务响应,与GarewayFilter的作用一样
    区别在于GatewayFilter通过配置定义,处理逻辑是固定的,而GlobalFilter的逻辑需要自己写代码实现,定义方式是实现GlobalFilter接口
    示例

    @Order(-1)  //值越小,优先级越高
    @Component
    public class AuthorizeFilter implements GlobalFilter {
        @Override
        public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
            // 1.获取请求参数
            MultiValueMap params = exchange.getRequest().getQueryParams();
            // 2.获取authorization参数
            String auth = params.getFirst("authorization");
            // 3.校验
            if ("admin".equals(auth)) {
                // 放行
                return chain.filter(exchange);
            }
            // 4.拦截
            // 4.1.禁止访问,设置状态码
            exchange.getResponse().setStatusCode(HttpStatus.FORBIDDEN);
            // 4.2.结束处理
            return exchange.getResponse().setComplete();
        }
    }
    

    6.4 过滤器执行顺序

    在这里插入图片描述

    • 全局过滤器与其他2类过滤器相比,永远是最后执行的,它的优先级只对其他全局过滤器起作用,order 值越小,优先级越高,执行顺序越靠前
    • 路由过滤器和默认过滤器会按照order的值进行排序,这个值由 Spring 指定,默认是按照声明顺序从1递增。
    • 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 的顺序执行

    七、跨域问题

    spring:
      cloud:
        gateway:
          # 。。。
          globalcors: # 全局的跨域处理
            add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
            corsConfigurations:
              '[/**]':
                allowedOrigins: # 允许哪些网站的跨域请求 
                  - "http://localhost:8090"
                allowedMethods: # 允许的跨域ajax的请求方式
                  - "GET"
                  - "POST"
                  - "DELETE"
                  - "PUT"
                  - "OPTIONS"
                allowedHeaders: "*" # 允许在请求中携带的头信息
                allowCredentials: true # 是否允许携带cookie
                maxAge: 360000 # 这次跨域检测的有效期
    

    ds

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论