自去年10月底发布GA版本后,Sentinel在近期发布了另外一个里程碑版本v1.4(最新的版本号是v1.4.1),加入了开发者关注的集群流控功能。java
为何要使用集群流控呢?假设咱们但愿给某个用户限制调用某个 API 的总 QPS 为 50,但机器数可能不少(好比有 100 台)。这时候咱们很天然地就想到,找一个 server 来专门来统计总的调用量,其它的实例都与这台 server 通讯来判断是否能够调用。这就是最基础的集群流控的方式。bash
那么这个 server 如何部署呢?最直观的方式就是做为独立的 token server 进程启动,独立部署:app
另外一种就是嵌入模式(Embedded),即做为内置的 token server 与服务在同一进程中启动,无需单独部署:ide
另外集群流控还能够解决流量不均匀致使整体限流效果不佳的问题。假设集群中有 10 台机器,咱们给每台机器设置单机限流阈值为 10 QPS,理想状况下整个集群的限流阈值就为 100 QPS。不过实际状况下流量到每台机器可能会不均匀,会致使总量没有到的状况下某些机器就开始限流:ui
所以仅靠单机维度去限制的话会没法精确地限制整体流量。而集群流控能够精确地控制整个集群的调用总量,结合单机限流兜底,能够更好地发挥流量控制的效果。spa
Sentinel 1.4.0 开始引入了集群流控模块,主要分为两个部分:Token Client 和 Token Server:3d
Sentinel 集群流控支持限流规则和热点规则两种规则。集群流控支持两种形式的阈值计算方式:code
Sentinel 集群流控服务端支持独立模式(Alone)以及嵌入模式(Embedded)。二者的优缺点对比:cdn
Sentinel 提供 API 来对 client / server 进行配置以及指定模式,可是机器多的时候不方便进行管理。通常咱们须要经过 Sentinel 控制台的集群流控管理功能来统一管理某个应用集群下全部的 token server 和 token client,灵活进行分配。server
配置是集群流控中比较重要的一部分。Sentinel 集群流控的配置主要包含几部分:
集群规则配置须要借助动态规则源。以集群流控规则为例,对于客户端,咱们能够用以前的方式向FlowRuleManager
注册动态规则源。而对于 Token Server,咱们须要向集群规则管理器 ClusterFlowRuleManager
注册规则源。咱们推荐的方式是在应用端注册动态规则源,而后在 Sentinel 控制台直接推送规则到配置中心,即 push 模式:
以嵌入模式为例,一个比较好的实践是:结合流量分布和实时负载状况来在服务集群中选取几台较为空闲的机器做为 Token Server,其它的机器做为 Token Client,划分红几组,分别归属各自的 Token Server 管理。最后组成一个映射表,相似于:
// ip: token server IP, port: token server port, clientSet: 所管辖的 token client 集合
[{"clientSet":["112.12.88.66@8729","112.12.88.67@8727"],"ip":"112.12.88.68","machineId":"112.12.88.68@8728","port":11111}]复制代码
而后像 Token Client / Token Server 通讯配置、集群流控模式等配置源均可以监听这个分配映射表对应的数据源,来解析本身的身份和相关通讯配置。当分配映射表变动时每台机器对应的身份和配置也会实时变动,实时生效。Sentinel 1.4.1 改进了 Sentinel 控制台集群流控的管理页面,能够直接以应用维度来分配 Token Server。能够参考本文后面的指引来使用。
其它的配置好比 Token Server 的命名空间集合(namespace set,用于指定该 Token Server 能够为哪些应用/分组服务)、最大容许的总 QPS 等,既能够经过 Sentinel 预留的 HTTP API 来变动配置,也能够经过注册动态配置源来进行配置。
下面咱们来看一下如何快速使用集群流控功能。接入集群流控模块的步骤以下:
(1)引入集群流控依赖
这里咱们以嵌入模式来运行 token server,即在应用集群中指定某台机器做为 token server,其它的机器指定为 token client。
首先咱们引入集群流控相关依赖:
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-cluster-client-default</artifactId>
<version>1.4.1</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-cluster-server-default</artifactId>
<version>1.4.1</version>
</dependency>复制代码
(2)配置动态规则源
要想使用集群流控功能,咱们须要在应用端配置动态规则源,并经过 Sentinel 控制台实时进行推送。流程以下所示:
以流控规则为例,假设咱们使用 ZooKeeper 做为配置中心,则能够向客户端 FlowRuleManager
注册 ZooKeeper 动态规则源:
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new ZookeeperDataSource<>(remoteAddress, path, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {}));
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());复制代码
另外咱们还须要针对 Token Server 注册集群规则数据源。因为嵌入模式下 token server 和 client 能够随时变换,所以咱们只需在每一个实例都向集群流控规则管理器 ClusterFlowRuleManager
注册动态规则源便可。Token Server 抽象出了命名空间(namespace)的概念,能够支持多个应用/服务,所以咱们须要注册一个自动根据 namespace 建立动态规则源的生成器:
// Supplier 会根据 namespace 生成的动态规则源,类型为 SentinelProperty<List<FlowRule>>,针对不一样的 namespace 生成不一样的规则源(监听不一样 namespace 的 path).
// 默认 namespace 为应用名(project.name)
// ClusterFlowRuleManager 针对集群限流规则,ClusterParamFlowRuleManager 针对集群热点规则,配置方式相似
ClusterFlowRuleManager.setPropertySupplier(namespace -> {
return new SomeDataSource(address, dataIdPrefix + namespace).getProperty();
});复制代码
(3)控制台进行改造适配动态规则源
咱们只需简单对 Sentinel 控制台进行改造便可直接将流控规则推送至配置中心。从 Sentinel 1.4.0 开始,Sentinel 控制台提供 DynamicRulePublisher
和 DynamicRuleProvider
接口用于实现应用维度的规则推送和拉取,并提供了 Nacos 推送的示例(位于 test 目录下)。咱们只须要实现本身的 DynamicRulePublisher
和 DynamicRuleProvider
接口并在 FlowControllerV2
类中相应位置经过 @Qualifier
注解指定对应的 bean name 便可,相似于:
@Autowired
@Qualifier("flowRuleNacosProvider")
private DynamicRuleProvider<List<FlowRuleEntity>> ruleProvider;
@Autowired
@Qualifier("flowRuleNacosPublisher")
private DynamicRulePublisher<List<FlowRuleEntity>> rulePublisher;复制代码
Sentinel 控制台提供应用维度推送的页面(/v2/flow
)。在上述配置完成后,咱们能够在此页面向配置中心推送规则:
(4)控制台分配 Token Server
当上面的步骤都完成后,咱们就能够在 Sentinel 控制台的“集群流控” Token Server 列表页面管理分配 token server 了。假设咱们启动了三个应用实例,咱们选择一个实例为 token server,其它两个为 token client:
页面上机器的显示方式为 ip@commandPort
,其中 commandPort
为应用端暴露给 Sentinel 控制台的端口。选择好之后,点击 保存 按钮,刷新页面便可以看到 token server 分配成功:
而且咱们能够在页面查看 token server 的链接状况:
(5)配置规则,观察效果
接下来咱们配置一条集群限流规则,限制 com.alibaba.csp.sentinel.demo.cluster.app.service.DemoService:sayHello(java.lang.String)
资源的集群总 QPS 为 10,选中“是否集群”选项,阈值模式选择整体阈值:
模拟流量同时请求这三台机器,过一段时间后观察效果。能够在监控页面看到对应资源的集群维度的总 QPS 稳定在 10:
集群流控可以精确地控制整个集群的 QPS,结合单机限流兜底,能够更好地发挥流量控制的效果。还有更多的场景等待你们发掘,好比:
尽管集群流控比较好用,但它不是万能的,只有在确实有必要的场景下才推荐使用集群流控。
另外若在生产环境使用集群限流,管控端还须要关注如下的问题:
将来咱们还计划实现集群流控多语言版本的客户端,并对接 Service Mesh,让 Sentinel 集群流控能够在更多场景下使用。