Spring Cloud 里的“守门大爷”:Sentinel 限流保平安
各位看官,大家好!今天咱就来聊聊 Spring Cloud 这个大家庭里一个非常重要的“成员”—— Sentinel,它就像咱们小区门口的“守门大爷”,负责把控流量,防止“坏人”(过高的流量)冲进来,破坏咱们系统的安全和稳定。
在微服务架构下,服务之间的调用关系错综复杂,一个请求可能要经过多个服务才能完成。如果某个服务扛不住压力,就会像多米诺骨牌一样,导致整个系统崩溃。这时候,Sentinel 就派上用场了。它能对服务进行限流、熔断、降级等操作,保证系统的可用性。
一、 什么是 Sentinel?它凭什么当“守门大爷”?
Sentinel,中文意思是“哨兵”,顾名思义,就是用来站岗放哨的。它是一个开源的、高可用的流量控制、熔断降级框架。
用官方的话来说,Sentinel 具有以下特点:
- 丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
- 完备的实时监控: Sentinel 提供实时的监控数据,方便我们了解系统的运行状况。
- 广泛的生态: Sentinel 提供了对 Spring Cloud、Dubbo 等流行框架的良好支持。
- SPI 可扩展性: Sentinel 提供了丰富的 SPI 接口,方便我们进行定制化开发。
简单来说,Sentinel 就是一个功能强大、性能优异、易于使用的流量控制框架。有了它,咱们就能轻松应对各种流量高峰,保证系统的稳定运行。
二、 Sentinel 能做些什么?“守门大爷”的十八般武艺
咱们的“守门大爷”Sentinel 可不是只会站岗,它可是身怀十八般武艺,样样精通。
-
流量控制(限流): 这是 Sentinel 最基本的功能。它可以限制某个接口或服务的请求速率,防止流量过大导致系统崩溃。
- QPS 限流: 限制每秒钟的请求数量。比如限制某个接口每秒最多只能处理 100 个请求。
- 线程数限流: 限制同时访问某个接口的线程数量。比如限制某个接口最多只能有 20 个线程同时访问。
- 其他限流方式: Sentinel 还支持基于调用关系、基于来源等多种限流方式。
-
熔断降级: 当某个服务出现故障时,Sentinel 可以自动熔断该服务,防止故障蔓延到整个系统。
- 平均响应时间熔断: 当某个接口的平均响应时间超过设定的阈值时,Sentinel 会熔断该接口。
- 异常比例熔断: 当某个接口的异常比例超过设定的阈值时,Sentinel 会熔断该接口。
- 异常数熔断: 当某个接口的异常数量超过设定的阈值时,Sentinel 会熔断该接口。
-
系统保护: Sentinel 可以对整个系统进行保护,防止系统负载过高导致崩溃。
- load 自适应保护: Sentinel 会根据系统的 load 情况自动调整流量控制策略。
- CPU 使用率保护: 当 CPU 使用率超过设定的阈值时,Sentinel 会拒绝部分请求。
- 入口流量控制: Sentinel 可以限制进入系统的总流量。
-
热点参数限流: 针对访问频率特别高的参数进行限流。比如针对某个用户的 ID 进行限流,防止恶意用户刷接口。
-
链路流控: 根据调用链路的拓扑关系进行流量控制。比如可以限制某个服务对下游服务的调用频率。
三、 如何在 Spring Cloud 中使用 Sentinel?手把手教你配置
说了这么多,咱们来点实际的,看看如何在 Spring Cloud 中使用 Sentinel。
1. 引入依赖
首先,在你的 Spring Cloud 项目中引入 Sentinel 的依赖。
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2. 配置 Sentinel
在 application.properties
或 application.yml
文件中配置 Sentinel。
spring:
application:
name: your-service-name
cloud:
sentinel:
enabled: true # 开启 Sentinel
transport:
dashboard: localhost:8080 # Sentinel 控制台地址
port: 8719 # sentinel客户端端口
# 关闭热点参数自动降级
degrade:
enabled: false
3. 定义资源
我们需要告诉 Sentinel 哪些接口或方法需要保护。可以使用 @SentinelResource
注解来定义资源。
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
@SentinelResource("hello")
public String hello() {
return "Hello, Sentinel!";
}
@GetMapping("/test")
@SentinelResource(value = "test", fallback = "testFallback", blockHandler = "testBlockHandler")
public String test() {
return "Test, Sentinel!";
}
public String testFallback(Throwable throwable) {
return "Test Fallback: " + throwable.getMessage();
}
public String testBlockHandler(com.alibaba.csp.sentinel.slots.block.BlockException blockException) {
return "Test Block Handler: " + blockException.getMessage();
}
}
@SentinelResource("hello")
:定义一个名为 "hello" 的资源,Sentinel 会对这个资源进行流量控制和熔断降级。value
:资源名称,必须唯一。fallback
:指定降级方法,当接口发生异常时,会调用该方法。注意:fallback 方法必须和原方法在同一个类中,且参数列表要兼容(可以多一个Throwable参数接收异常)。blockHandler
:指定限流或熔断时的处理方法,当接口被限流或熔断时,会调用该方法。注意:blockHandler 方法必须和原方法在同一个类中,且参数列表要兼容(可以多一个BlockException参数接收异常)。
4. 配置限流规则
启动 Sentinel 控制台,地址就是上面配置的 localhost:8080
。
在控制台上,可以配置各种限流规则。比如,我们可以配置 "hello" 接口的 QPS 限流规则,限制每秒钟最多只能处理 5 个请求。
配置流程:
- 访问Sentinel控制台,点击“簇点链路”或者“资源”,找到你需要配置的资源(比如 “hello”)。
- 点击 “流控”,添加流控规则。
- 配置流控规则:
- 资源名:默认为你选择的资源,比如“hello”
- 针对来源:默认为
default
,表示不区分来源。 - 阈值类型:选择 QPS 或线程数。
- 单机阈值:设置具体的阈值,比如 5(表示每秒最多允许 5 个请求)。
- 流控模式:选择直接拒绝、Warm Up、排队等待。
- 是否集群:根据需要选择是否开启集群流控。
5. 测试
启动你的 Spring Cloud 项目,然后访问 /hello
接口。如果访问频率超过了设定的阈值,Sentinel 就会拒绝部分请求。当你配置了blockHandler
方法,就会执行该方法,返回自定义的提示信息。
四、 代码示例:更深入的讲解
光说不练假把式,咱们来几个更具体的代码示例,帮助大家更深入地理解 Sentinel 的使用。
示例 1:QPS 限流
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class RateLimitController {
@GetMapping("/rateLimit")
@SentinelResource(value = "rateLimit", blockHandler = "rateLimitBlockHandler")
public String rateLimit() {
return "Rate Limit Success!";
}
public String rateLimitBlockHandler(com.alibaba.csp.sentinel.slots.block.BlockException blockException) {
return "Rate Limit Blocked!";
}
}
在 Sentinel 控制台上,配置 "rateLimit" 接口的 QPS 限流规则,限制每秒钟最多只能处理 2 个请求。
示例 2:熔断降级
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DegradeController {
@GetMapping("/degrade")
@SentinelResource(value = "degrade", fallback = "degradeFallback")
public String degrade() throws InterruptedException {
// 模拟服务不稳定,偶尔会抛出异常
if (Math.random() < 0.5) {
throw new RuntimeException("Service Unavailable!");
}
Thread.sleep(100); // 模拟服务响应时间
return "Degrade Success!";
}
public String degradeFallback(Throwable throwable) {
return "Degrade Fallback: " + throwable.getMessage();
}
}
在 Sentinel 控制台上,配置 "degrade" 接口的异常比例熔断规则,设置异常比例为 0.6。
示例 3:热点参数限流
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HotParamController {
@GetMapping("/hotParam")
@SentinelResource(value = "hotParam", blockHandler = "hotParamBlockHandler")
public String hotParam(@RequestParam String id) {
return "Hot Param: " + id;
}
public String hotParamBlockHandler(String id, com.alibaba.csp.sentinel.slots.block.BlockException blockException) {
return "Hot Param Blocked: " + id;
}
}
在 Sentinel 控制台上,配置 "hotParam" 接口的热点参数限流规则,针对参数 "id" 进行限流。
五、 Sentinel 的高级用法:更上一层楼
除了上面介绍的基本用法,Sentinel 还有很多高级用法,可以帮助我们更好地保护系统。
- 自定义规则: Sentinel 提供了 SPI 接口,我们可以自定义限流规则、熔断规则等。
- 集群流控: 在分布式环境下,可以使用 Sentinel 的集群流控功能,对整个集群的流量进行控制。
- 动态配置: 可以使用 Nacos、Consul 等配置中心,动态更新 Sentinel 的规则。
- 监控告警: 可以将 Sentinel 的监控数据接入 Prometheus、Grafana 等监控系统,实现实时监控和告警。
六、 Sentinel 的优缺点:客观评价
任何事物都有两面性,Sentinel 也不例外。
优点:
- 功能强大,支持多种限流和熔断策略。
- 性能优异,对系统性能影响较小。
- 易于使用,配置简单。
- 社区活跃,文档完善。
缺点:
- 学习成本较高,需要一定的学习时间才能掌握。
- 配置规则较为繁琐,需要手动配置。
- 对 Spring Cloud 的版本有一定要求。
七、 Sentinel 与 Hystrix 的对比:谁更胜一筹?
在 Sentinel 出现之前,Hystrix 是 Spring Cloud 中常用的熔断降级框架。那么,Sentinel 和 Hystrix 相比,谁更胜一筹呢?
特性 | Sentinel | Hystrix |
---|---|---|
功能 | 限流、熔断、降级、系统保护、热点参数限流 | 熔断、降级 |
性能 | 较高 | 较低 |
易用性 | 较易 | 较易 |
社区活跃度 | 较高 | 较低(已停止维护) |
监控 | 提供实时监控数据 | 需要集成第三方监控系统,且数据不如Sentinel丰富 |
生态 | 与 Spring Cloud 深度集成 | 与 Spring Cloud 集成度一般 |
总的来说,Sentinel 在功能、性能、社区活跃度等方面都优于 Hystrix。Hystrix 已经停止维护,建议在新项目中使用 Sentinel。
八、总结:Sentinel 是 Spring Cloud 的好帮手
Sentinel 就像咱们 Spring Cloud 社区的“守门大爷”,它能有效地保护我们的系统,防止流量过大导致崩溃。虽然学习 Sentinel 需要花费一些时间,但它的功能和性能绝对值得我们投入精力。
希望这篇文章能帮助大家更好地理解和使用 Sentinel。记住,有了 Sentinel,咱们的 Spring Cloud 系统就能更加安全、稳定地运行啦!
最后,祝大家编码愉快,bug 远离!