第三章:核心模块解析之-ruoyi-gateway

1,870 阅读6分钟

一、网关概念

在微服务架构中,一个系统会被拆封成多个微服务,每个微服务可以单独对外提供服务,如果需要统一的对外服务入口则需要网关来实现,网关记录业务微服务的服务名和地址,每次调用可以正确的映射到正确的真实地址上。Gateway 是 Spring Cloud 的一个重要组件,它是一个基于 Spring WebFlux 的 API 网关。Spring Cloud Gateway 旨在替代 Netflix Zuul,并提供了一种简单有效的方式来路由到 API 和微服务。以下是关于 Spring Cloud Gateway 的一些关键特性与概念:

关键特性

  1. 动态路由:可以根据不同的路径、请求头等条件将请求路由到不同的微服务。
  2. 过滤器:可以添加自定义逻辑来修改请求和响应,例如添加认证、监控、限流等功能。
  3. 限流:可以对通过网关的请求进行限制,防止过载。
  4. 断路器:在服务出现故障时,可以自动地切断与该服务的连接,避免雪崩效应。
  5. 高可用性:支持集群部署,可以通过负载均衡机制提高系统的可用性和性能。

主要组成部分

  • Route:路由是网关的基本配置单元,包含ID、目标URI、一系列谓词(Predicates)和过滤器(Filter)。

    • 谓词 (Predicates):用于匹配HTTP请求,如果匹配成功,则该路由将被用于处理请求。
    • 过滤器 (Filters):用于修改进入和离开的请求/响应。

使用场景

  • 微服务路由:作为微服务间的路由层,根据请求将流量转发到正确的微服务实例。
  • 统一入口点:为所有客户端提供一个统一的入口点,简化客户端与后端服务之间的交互。
  • 安全性和认证:可以在网关级别实现认证和授权,减少每个微服务的安全负担。
  • 监控和日志:在网关层面收集日志和监控数据,便于分析和调试。

二、网关核心依赖分析

image.png 说明

<!-- SpringCloud 网关 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>

<!-- SpringCloud 阿里Nacos服务发现-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

<!-- SpringCloud 阿里Nacos 配置中心 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

<!-- SpringCloud 阿里 Sentinel限流熔断 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

<!-- SpringCloud Alibaba Sentinel Gateway -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>

<!-- Sentinel Datasource Nacos -->
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

<!-- SpringBoot Actuator -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

<!-- SpringCloud Loadbalancer -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>

三、代码实践配置角度

利用Gateway作为微服务网关,需要注册中心进行服务注册,在本次实践中,我们选用nacos作为注册中心。 ruoyi-gateway模块

image.png

1.首先,该模块加载了 bootstrap.yml 文件,其中配置了 Nacos 服务的地址,以此实现当前项目与 Nacos 服务的关联。

image.png

2.在 bootstrap.yml 文件中,进一步加载了 Nacos 中的以下配置文件:application-dev.yml, ruoyi-gateway-dev.yml, 和 sentinel-ruoyi-gateway.yml。这些配置文件共同作用于项目的初始化设置。

image.png

3. 此模块通过与 Sentinel 关联,实现了对其他各个模块的流量控制。具体的限流规则定义在 sentinel-ruoyi-gateway 配置中。

   [    {    "resource": "ruoyi-auth",    "count": 500,    "grade": 1,    "limitApp": "default",    "strategy": 0,    "controlBehavior": 0    },        {    "resource": "ruoyi-system",    "count": 1000,    "grade": 1,    "limitApp": "default",    "strategy": 0,    "controlBehavior": 0    },        {    "resource": "ruoyi-job",    "count": 300,    "grade": 1,    "limitApp": "default",    "strategy": 0,    "controlBehavior": 0    },    {    "resource": "ruoyi-file",    "count": 300,    "grade": 1,    "limitApp": "default",    "strategy": 0,    "controlBehavior": 0    }    ]

Sentinel 是阿里巴巴开源的面向分布式服务架构的高可用性保障组件,主要用于服务的流量防卫,如流量控制、熔断降级、系统负载保护等。下面是这个限流配置每个字段的解释:

Resource: 这是指被保护的资源名称,它对应需要实施限流措施的微服务或特定操作。例如,“ruoyi-auth”表示该限流规则适用于标记为“ruoyi-auth”的资源

Grade: 这是指限流的模式,值为 1 表示采用 QPS(每秒查询率)模式。Sentinel 还支持其他模式,比如线程数限流(值为 0)。

LimitApp: 这个参数指定流控针对的调用来源。设置为 "default" 表示不区分调用来源,即对所有来源的请求均执行限流。若指定为某个具体的服务名称,则仅对该服务的请求进行限流。

Strategy: 这个参数定义了调用关系的限流策略。值为 0 表示直接限流(即直接对访问 ruoyi-auth 的请求进行限流)。还有其他模式,例如链路限流(值为 1),用于在复杂的调用链中实现更精细的流量控制。

ControlBehavior: 这个参数定义了流量控制的效果。值为 0 表示快速失败,意味着当请求达到限流阈值时,系统会立即拒绝多余的请求,并返回一个快速失败的响应。Sentinel 还支持其他控制效果,例如预热模式、排队等待等。

四、功能实现角度【验证码】

用户如何实现验证码,以及该功能如何与 Spring Gateway 联系起来。

1. 验证码功能的类清单

image.png 在 RuoYi-Cloud 项目中,验证码的实现主要利用了 Google 的 Kaptcha 库来生成验证码图片,并使用 Redis 进行验证码数据的存储。下面我们将详细介绍验证码的实现过程。

1.1 主要组件

  • Kaptcha:用于生成验证码图片。
  • Redis:用于存储生成的验证码。
  • Spring Cloud Gateway:用于路由和过滤器处理。

1.2 关键类介绍

  • CaptchaConfig:配置类,用于初始化 Kaptcha 并定义验证码类型。
  • CaptchaProperties:配置属性类,定义验证码相关的配置项。
  • ValidateCodeServiceImpl:服务实现类,处理验证码的生成和验证。
  • RouterFunctionConfiguration:配置类,定义路由函数。
  • ValidateCodeHandler:处理器,处理验证码的请求。
  • ValidateCodeFilter:过滤器,用于验证验证码。

2. 验证码的实现细节

2.1 验证码的获取

定义路由函数 RouterFunction
  • 在 RouterFunctionConfiguration 类中定义了获取验证码的路由函数。
  • 路由函数定义了处理器 HandlerFunction,该处理器负责处理验证码的请求。
处理器 HandlerFunction
  • 在 ValidateCodeHandler 类中定义了 HandlerFunction,它关联了 RouteFunction 和 ValidateCodeService
  • 当请求到达时,DispatcherHandler 会将请求转发给 HandlerFunction,后者再调用 ValidateCodeService 来生成验证码。
配置类 CaptchaConfig
  • 在 CaptchaConfig 类中定义了两个 Bean,分别是字符验证码和数字验证码的配置。
  • 这些配置初始化了 Kaptcha 对象,用于生成不同类型的验证码。
如何生成验证码
  • 数字验证码

    • 创建数学结果(如随机数字)。
    • 生成验证码图片。
  • 字符验证码

    • 创建字符序列。
    • 生成验证码图片。
  • 生成验证码后,将验证码的结果缓存到 Redis 中。

  • 返回前端一个 UUID 和 Base64 编码的图片。

2.2 验证码的校验

  • 在 Nacos 配置中心为 auth 模块配置了验证码过滤器。

  • 使用 YAML 文件配置了 ruoyi-auth 路由的过滤器列表。

  • 如果请求匹配了 Path=/auth/**,则依次执行以下过滤器:

    1. AuthFilter (order=-200):身份验证过滤器。
    2. XssFilter (order=-100):跨站脚本防护过滤器。
    3. CacheRequestFilter (order=1):缓存请求过滤器。
    4. ValidateCodeFilter (order=2):验证码验证过滤器。
    5. StripPrefix (order=3):路径前缀移除过滤器。
  • ValidateCodeFilter 的作用是在请求处理前验证客户端提交的验证码。如果验证码正确,则请求可以继续传递给下一个过滤器或者目标服务;如果验证码错误,则请求会被拒绝,并返回相应的错误信息。

五、快速启动

image.png 查看服务列表 image.png