TypechoJoeTheme

香草物语

统计
登录
用户名
密码
/
注册
用户名
邮箱
输入密码
确认密码

Spring Cloud集成Gateway

Laughing博主
2021-07-29
/
0 评论
/
1,053 阅读
/
1166 个字
/
百度已收录
07/29
本文最后更新于2024年03月16日,已超过43天没有更新。如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!

一、SpringCloud Gateway 简介

SpringCloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。

SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 2.0之前的非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

Spring Cloud Gateway 的目标,不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。

二、SpringCloud Gateway 特征

SpringCloud官方,对SpringCloud Gateway 特征介绍如下:

  • 基于 Spring Framework 5,Project Reactor 和 Spring Boot 2.0
  • 集成 Hystrix 断路器
  • 集成 Spring Cloud DiscoveryClient
  • Predicates 和 Filters 作用于特定路由,易于编写的 Predicates 和 Filters
  • 具备一些网关的高级功能:动态路由、限流、路径重写

从以上的特征来说,和Zuul的特征差别不大。SpringCloud Gateway和Zuul主要的区别,还是在底层的通信框架上。

简单说明一下上文中的三个术语:

  1. Filter(过滤器):

和Zuul的过滤器在概念上类似,可以使用它拦截和修改请求,并且对上游的响应,进行二次处理。过滤器为org.springframework.cloud.gateway.filter.GatewayFilter类的实例。

  1. Route(路由):

网关配置的基本组成模块,和Zuul的路由配置模块类似。一个Route模块由一个ID,一个目标URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配,目标URI会被访问。

  1. Predicate(断言):

这是一个 Java 8 的Predicate,可以使用它来匹配来自HTTP请求的任何内容,例如headers或参数。断言的输入类型是一个 ServerWebExchange

三、Spring Cloud Gateway的处理流程

客户端向 Spring Cloud Gateway 发出请求。然后在Gateway Handler Mapping中找到与请求相匹配的路由,将其发送到Gateway Web HandlerHandler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(pre)或之后(post)执行业务逻辑。

四、路由匹配规则

对于这种配置类的,我们一般情况都会放到配置文件中去配置。
Spring Cloud Gateway 的功能很强大,我们仅仅通过 Predicates 的设计就可以看出来,前面我们只是使用了 predicates 进行了简单的条件匹配,其实 Spring Cloud Gataway 帮我们内置了很多 Predicates 功能。

Spring Cloud Gateway 是通过 Spring WebFlux 的 HandlerMapping 做为底层支持来匹配到转发路由,Spring Cloud Gateway 内置了很多 Predicates 工厂,这些 Predicates 工厂通过不同的 HTTP 请求参数来匹配,多个 Predicates 工厂可以组合使用。

代码Demo

父工程依赖

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>2.3.12.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR12</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
<!--                <version>2.1.0.RELEASE</version>-->
                <version>2.2.1.RELEASE</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${mybatis.spring.boot.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

当前模块依赖

 <dependencies>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

    </dependencies>

配置文件

server:
  port: 9527
spring:
  application:
    name: cloud-gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.120.180:8848
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: payment-routh
          uri: lb://nacos-provider-payment # 服务名称
          predicates:
            - Path=/app/**
            - Header=username,laughing

可以看到gateway的路由匹配规格主要是包含iduripredicates
id随意指定,唯一即可。
uri代表配置的路径,可以匹配URL或者服务名称,如果是服务名称,以lb:打头。
predicates代表断言,条件为true时才能进入对应的路径。
说白了 Predicate 就是为了实现一组匹配规则,方便让请求过来找到对应的 Route 进行处理,接下来我们接下 Spring Cloud GateWay 内置几种 Predicate 的使用。
假定转发uri都设定为lb://nacos-provider-payment

规则实例说明
Path- Path=/gate/,/rule/当请求的路径为gate、rule开头的时,转发到nacos-provider-payment服务
Before- Before=2017-01-20T17:42:47.789-07:00[America/Denver]在某个时间之前的请求才会被转发到nacos-provider-payment服务
After- After=2017-01-20T17:42:47.789-07:00[America/Denver]在某个时间之后的请求才会被转发到nacos-provider-payment服务
Between- Between=2017-01-20T17:42:47.789-07:00[America/Denver],2017-01-21T17:42:47.789-07:00[America/Denver]在某个时间段之间的才会被转发
Cookie- Cookie=chocolate, ch.p名为chocolate的表单或者满足正则ch.p的表单才会被匹配到进行请求转发
Header- Header=X-Request-Id, \d+携带参数X-Request-Id或者满足\d+的请求头才会匹配
Host- Host=www.xiangcaowuyu.net当主机名为www.xiangcaowuyu.net的时候直接转发到nacos-provider-payment服务
Method- Method=GET只有GET方法才会匹配转发请求,还可以限定POST、PUT等请求方式

测试我们上面代码的匹配规则

如果我们访问的路径是/echo开头,并且Headerusername=laughing就转发到nacos-provider-payment服务。
第一次正常访问
第二次,我们配置Header
可以看到报404
第三次,我们配置Header但是参数值设置为test,可以看到也是报404
其他参数配置我们不再测试。

五、过滤器规则(Filter)

过滤规则实例说明
PrefixPath- PrefixPath=/app在请求路径前加上app
RewritePath- RewritePath=/test, /app/test访问localhost:9022/test,请求会转发到localhost:8001/app/test
SetPathSetPath=/app/{path}通过模板设置路径,转发的规则时会在路径前增加app,{path}表示原请求路径
RedirectTo 重定向
RemoveRequestHeader 去掉某个请求头信息

测试Demo

我们只测试一个PrefixPath

服务提供者

   @GetMapping(value = "app/echo/{string}")
    public String echo1(@PathVariable("string") String string) {
        return "app/echo/{string} " + string+"\t当前服务端口:"+serverPort;
    }

配置文件

server:
  port: 9527
spring:
  application:
    name: cloud-gateway-service
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.120.180:8848
    gateway:
      discovery:
        locator:
          enabled: true
      routes:
        - id: payment-routh
          uri: lb://nacos-provider-payment # 服务名称
          predicates:
            - Path=/**
          filters:
            PrefixPath=/app

测试

Spring CloudSpring BootNacosSentinelSpring Cloud AlibabaGatewayZuul
朗读
赞(1)
赞赏
感谢您的支持,我会继续努力哒!
版权属于:

香草物语

本文链接:

https://www.xiangcaowuyu.net/java/spring-cloud-integration-gateway.html(转载时请注明本文出处及文章链接)

评论 (0)