🍓 简介:java系列技术分享(👉持续更新中…🔥)
🍓 初衷:一起学习、一起进步、坚持不懈
🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏
🍓 希望这篇文章对你有所帮助,欢迎点赞 👍 收藏 ⭐留言 📝🍓 更多文章请点击
文章目录
- 一、Gateway简介
 - 二、Spring Cloud Gateway入门案例
 - 2.1 父工程依赖
 - 2.2 gateway网关搭建
 - 2.2.1 pom依赖
 - 2.2.2 yml配置
 - 2.2.3 可能存在的问题
 - 启动报错
 - 如果uri使用lb负载均衡配置,可能会报错如下:
 
- 2.2.4 调用测试成功
 
- 三、网关路由流程图
 - 四、Nginx网关和GateWay网关的区别
 - 五、路由断言工厂
 - 六、过滤器工厂
 - 6.1 GatewayFilter路由过滤器
 - 6.2 默认过滤器
 - 6.3 全局过滤器
 - 6.4 过滤器执行顺序
 
- 七、跨域问题
 
一、Gateway简介
Gateway官网:https://spring.io/projects/spring-cloud-gateway
 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 父工程依赖
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.6.3</version>
        <relativePath/>
    </parent>
    
	 <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>2021.0.1</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.0.1.0</spring-cloud-alibaba.version>
     </properties>
    <dependencyManagement>
        <!-- springCloud -->
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- spring cloud alibaba是阿里巴巴集团针对服务开发所提供的一套解决方案 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
 
2.2 gateway网关搭建
2.2.1 pom依赖
    <dependencies>
        <!-- nacos作为注册中心的依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--网关-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>
 
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这个依赖 - 或者如下排除
 
<dependency>
    <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-gateway</artifactId>
     <exclusions>
         <exclusion>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </exclusion>
         <exclusion>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-webflux</artifactId>
         </exclusion>
     </exclusions>
</dependency>
 
如果uri使用lb负载均衡配置,可能会报错如下:
启动正常,调用可能会出现,没有可用的服务等信息
There was an unexpected error (type=Service Unavailable, status=503).
 
添加如下依赖
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
 
2.2.4 调用测试成功

未使用网关
 
 使用网关10010端口调用

三、网关路由流程图

四、Nginx网关和GateWay网关的区别
-  
Nignx是流量网关,GateWay是业务网关
 -  
流量网关相当于访问的一个总入口,前端页面的一个容器,类似于防火。主要的功能有管理日志,流量监控,黑白名单,请求的负载均衡,全局限流等。
 -  
而业务网关是针对具体的后端应用和服务,主要的功能是缓存策略、鉴权策略等
 -  
一般流量网关配置在前,业务网关配置在后
 -  
Nginx是C语言写的,GateWay是java语言写的
 -  
GateWay主要是路由、断言和过滤器,利用这些可以做流控
 -  
Nginx主要是负载均衡,反向代理,以及做web服务器
 
五、路由断言工厂
官网12种示例地址 : https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

 
六、过滤器工厂
6.1 GatewayFilter路由过滤器
官网示例地址 : https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories
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<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        MultiValueMap<String, String> 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 # 这次跨域检测的有效期
 
![]()





















