一、网关概念
在微服务架构中,一个系统会被拆封成多个微服务,每个微服务可以单独对外提供服务,如果需要统一的对外服务入口则需要网关来实现,网关记录业务微服务的服务名和地址,每次调用可以正确的映射到正确的真实地址上。Gateway 是 Spring Cloud 的一个重要组件,它是一个基于 Spring WebFlux 的 API 网关。Spring Cloud Gateway 旨在替代 Netflix Zuul,并提供了一种简单有效的方式来路由到 API 和微服务。以下是关于 Spring Cloud Gateway 的一些关键特性与概念:
关键特性
- 动态路由:可以根据不同的路径、请求头等条件将请求路由到不同的微服务。
- 过滤器:可以添加自定义逻辑来修改请求和响应,例如添加认证、监控、限流等功能。
- 限流:可以对通过网关的请求进行限制,防止过载。
- 断路器:在服务出现故障时,可以自动地切断与该服务的连接,避免雪崩效应。
- 高可用性:支持集群部署,可以通过负载均衡机制提高系统的可用性和性能。
主要组成部分
-
Route:路由是网关的基本配置单元,包含ID、目标URI、一系列谓词(Predicates)和过滤器(Filter)。
- 谓词 (Predicates):用于匹配HTTP请求,如果匹配成功,则该路由将被用于处理请求。
- 过滤器 (Filters):用于修改进入和离开的请求/响应。
使用场景
- 微服务路由:作为微服务间的路由层,根据请求将流量转发到正确的微服务实例。
- 统一入口点:为所有客户端提供一个统一的入口点,简化客户端与后端服务之间的交互。
- 安全性和认证:可以在网关级别实现认证和授权,减少每个微服务的安全负担。
- 监控和日志:在网关层面收集日志和监控数据,便于分析和调试。
二、网关核心依赖分析
说明
<!-- 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模块
1.首先,该模块加载了 bootstrap.yml 文件,其中配置了 Nacos 服务的地址,以此实现当前项目与 Nacos 服务的关联。
2.在 bootstrap.yml 文件中,进一步加载了 Nacos 中的以下配置文件:application-dev.yml, ruoyi-gateway-dev.yml, 和 sentinel-ruoyi-gateway.yml。这些配置文件共同作用于项目的初始化设置。
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. 验证码功能的类清单
在 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/**,则依次执行以下过滤器:- AuthFilter (
order=-200):身份验证过滤器。 - XssFilter (
order=-100):跨站脚本防护过滤器。 - CacheRequestFilter (
order=1):缓存请求过滤器。 - ValidateCodeFilter (
order=2):验证码验证过滤器。 - StripPrefix (
order=3):路径前缀移除过滤器。
- AuthFilter (
-
ValidateCodeFilter 的作用是在请求处理前验证客户端提交的验证码。如果验证码正确,则请求可以继续传递给下一个过滤器或者目标服务;如果验证码错误,则请求会被拒绝,并返回相应的错误信息。
五、快速启动
查看服务列表