你好,这里是codetrend专栏“SpringCloud2023实战”。
本文简单介绍SpringCloud2023中使用Sentinel进行限流管理。
前言
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。
Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件,主要以流量为切入点,从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。
Sentinel 同时提供系统维度的自适应保护能力。
防止雪崩,是系统防护中重要的一环。当系统负载较高的时候,如果还持续让请求进入,可能会导致系统崩溃,无法响应。在集群环境下,网络负载均衡会把本应这台机器承载的流量转发到其它的机器上去。
如果这个时候其它的机器也处在一个边缘状态的时候,这个增加的流量就会导致这台机器也崩溃,最后导致整个集群不可用。
Spring Cloud Alibaba 默认为 Sentinel 整合了 Servlet、RestTemplate、FeignClient 和 Spring WebFlux。
Sentinel 在 Spring Cloud 生态中,不仅补全了 Hystrix 在 Servlet 和 RestTemplate 这一块的空白,而且还完全兼容了 Hystrix 在 FeignClient 中限流降级的用法,并且支持运行时灵活地配置和调整限流降级规则。
Sentinel工作机制
Sentinel 的使用可以分为两个部分:
- 核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 8 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持(见 主流框架适配)。
- 控制台(Dashboard):Dashboard 主要负责管理推送规则、监控、管理机器信息等。
Sentinel 的主要工作机制如下:
- 对主流框架提供适配或者显示的 API,来定义需要保护的资源,并提供设施对资源进行实时统计和调用链路分析。
- 根据预设的规则,结合对资源的实时统计信息,对流量进行控制。同时,Sentinel 提供开放的接口,方便您定义及改变规则。
- Sentinel 提供实时的监控系统,方便您快速了解目前系统的状态。
Sentinel特点
Sentinel 具有以下特征:
- 丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、实时熔断下游不可用应用等。
- 完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
- 广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
- 完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展点。您可以通过实现扩展点,快速的定制逻辑。例如定制规则管理、适配数据源等。
Sentinel集成之控制台(Dashboard)
Sentinel 控制台提供一个轻量级的控制台,它提供机器发现、单机资源实时监控、集群资源汇总,以及规则管理的功能。您只需要对应用进行简单的配置,就可以使用这些功能。
- 获取控制台。从 release 页面 - https://github.com/alibaba/Sentinel/releases 下载最新版本的控制台 jar 包。
- 启动控制台。 Sentinel 控制台是一个标准的 Spring Boot 应用,以 Spring Boot 的方式运行 jar 包即可。
java -Dserver.port=10300 -Dcsp.sentinel.dashboard.server=localhost:10300 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
# 如若8080端口冲突,可使用 -Dserver.port=新端口 进行设置。
- 配置控制台信息,application.yml 。
spring:
cloud:
sentinel:
transport:
port: 10201
dashboard: localhost:10300
这里的 spring.cloud.sentinel.transport.port 端口配置会在应用对应的机器上启动一个 Http Server,该 Server 会与 Sentinel 控制台做交互。比如 Sentinel 控制台添加了一个限流规则,会把规则数据 push 给这个 Http Server 接收,Http Server 再将规则注册到 Sentinel 中。
Sentinel集成之普通服务
引入pom.xml
- 引入Sentinel主要是引入
spring-cloud-starter-alibaba-sentinel
。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<dependencies>
<!-- sentinel核心包引入 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
</dependency>
<!-- sentinel-springboot引入 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
</project>
修改配置
- 新增配置文件
application.yml
,配置主要是spring.cloud.sentinel
下面的配置。
spring.application.name: banana-client4-sentinel
spring:
cloud:
sentinel:
transport:
port: 10201
dashboard: localhost:10300
zookeeper:
connect-string: localhost:2181
接口demo
- 通过访问
http://localhost:10200/client4/swagger-ui.html
,输入账号密码 yulin/123yl. 就可以访问到最新的接口文档,验证限流是否开启成功。
@Service
public class TestService {
@SentinelResource(value = "sayHello")
public String sayHello(String name) {
return "Hello, " + name;
}
}
@RestController
public class TestController {
@Autowired
private TestService service;
@GetMapping(value = "/hello/{name}")
public String apiHello(@PathVariable String name) {
return service.sayHello(name);
}
}
- 在控制面板设置
http://localhost:10200/client4/hello
的QPS为5。通过如下脚本验证限流是否成功:
import requests
token_list =[]
for j in range(10):
token_list.append(str(j)+'hello')
response = requests.get('http://localhost:10200/client4/hello/'+str(j)+'hello','hello')
print(response.text)
输出文档如下:
Hello, 0hello
Hello, 1hello
Hello, 2hello
Hello, 3hello
Hello, 4hello
Blocked by Sentinel (flow limiting)
Blocked by Sentinel (flow limiting)
Blocked by Sentinel (flow limiting)
Blocked by Sentinel (flow limiting)
Blocked by Sentinel (flow limiting)
Sentinel集成之OpenFeign
pom.xml和配置修改
Feign 适配整合在 Spring Cloud Alibaba 中,可以参考 Spring Cloud Alibaba Sentinel 文档 进行接入。
Sentinel 适配了 Feign 组件。如果想使用,除了引入 spring-cloud-starter-alibaba-sentinel
的依赖外还需要 2 个步骤:
- 配置文件打开 Sentinel 对 Feign 的支持:
feign.sentinel.enabled=true
- 加入
spring-cloud-starter-openfeign
依赖使 Sentinel starter 中的自动化配置类生效:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
demo验证代码
@FeignClient(name = "service-provider", fallback = EchoServiceFallback.class, configuration = FeignConfiguration.class)
public interface EchoService {
@RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
String echo(@PathVariable("str") String str);
}
class FeignConfiguration {
@Bean
public EchoServiceFallback echoServiceFallback() {
return new EchoServiceFallback();
}
}
class EchoServiceFallback implements EchoService {
@Override
public String echo(@PathVariable("str") String str) {
return "echo fallback";
}
}
- EchoService 接口中方法 echo 对应的资源名为
GET:http://service-provider/echo/{str}
。 通过对该资源限流配置即可。 - 实际验证失败,可能是没有开发到springcloud2023。
Sentinel集成之Gateway
若想跟 Sentinel Starter 配合使用,需要加上 spring-cloud-alibaba-sentinel-gateway
依赖,同时需要添加 spring-cloud-starter-gateway
依赖来让 spring-cloud-alibaba-sentinel-gateway
模块里的 Spring Cloud Gateway 自动化配置类生效:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
同时请将 spring.cloud.sentinel.filter.enabled
配置项置为 false(若在网关流控控制台上看到了 URL 资源,就是此配置项没有置为 false)。Sentinel 网关流控默认的粒度是 route 维度以及自定义 API 分组维度,默认不支持 URL 粒度。
文档来自Sentinel文档。这里不仔细展开开发和说明,后续在网关业务层进行配置和说明。
完整源码信息查看可以在gitee或者github上搜索r0ad
。
关于作者
来自一线全栈程序员nine的探索与实践,持续迭代中。
欢迎关注或者点赞~