Sentinel(六)之集群流控
转载自 集群流控
介绍
为什么要使用集群流控呢?假设我们希望给某个用户限制调用某个 API 的总 QPS 为 50,但机器数可能很多(比如有 100 台)。这时候我们很自然地就想到,找一个 server 来专门来统计总的调用量,其它的实例都与这台 server 通信来判断是否可以调用。这就是最基础的集群流控的方式。
另外集群流控还可以解决流量不均匀导致总体限流效果不佳的问题。假设集群中有 10 台机器,我们给每台机器设置单机限流阈值为 10 QPS,理想情况下整个集群的限流阈值就为 100 QPS。不过实际情况下流量到每台机器可能会不均匀,会导致总量没有到的情况下某些机器就开始限流。因此仅靠单机维度去限制的话会无法精确地限制总体流量。而集群流控可以精确地控制整个集群的调用总量,结合单机限流兜底,可以更好地发挥流量控制的效果。
集群流控中共有两种身份:
- Token Client:集群流控客户端,用于向所属 Token Server 通信请求 token。集群限流服务端会返回给客户端结果,决定是否限流。
- Token Server:即集群流控服务端,处理来自 Token Client 的请求,根据配置的集群规则判断是否应该发放 token(是否允许通过)。
模块结构
Sentinel 1.4.0 开始引入了集群流控模块,主要包含以下几部分:
sentinel-cluster-common-default
: 公共模块,包含公共接口和实体sentinel-cluster-client-default
: 默认集群流控 client 模块,使用 Netty 进行通信,提供接口方便序列化协议扩展sentinel-cluster-server-default
: 默认集群流控 server 模块,使用 Netty 进行通信,提供接口方便序列化协议扩展;同时提供扩展接口对接规则判断的具体实现(TokenService
),默认实现是复用sentinel-core
的相关逻辑
集群流控规则
规则
FlowRule
添加了两个字段用于集群限流相关配置:
private boolean clusterMode; // 标识是否为集群限流配置
private ClusterFlowConfig clusterConfig; // 集群限流相关配置项
其中 用一个专门的 ClusterFlowConfig
代表集群限流相关配置项,以与现有规则配置项分开:
// (必需)全局唯一的规则 ID,由集群限流管控端分配.
private Long flowId;// 阈值模式,默认(0)为单机均摊,1 为全局阈值.
private int thresholdType = ClusterRuleConstant.FLOW_THRESHOLD_AVG_LOCAL;private int strategy = ClusterRuleConstant.FLOW_CLUSTER_STRATEGY_NORMAL;// 在 client 连接失败或通信失败时,是否退化到本地的限流模式
private boolean fallbackToLocalWhenFail = true;
flowId
代表全局唯一的规则 ID,Sentinel 集群限流服务端通过此 ID 来区分各个规则,因此务必保持全局唯一。一般 flowId 由统一的管控端进行分配,或写入至 DB 时生成。thresholdType
代表集群限流阈值模式。其中单机均摊模式下配置的阈值等同于单机能够承受的限额,token server 会根据客户端对应的 namespace(默认为project.name
定义的应用名)下的连接数来计算总的阈值(比如独立模式下有 3 个 client 连接到了 token server,然后配的单机均摊阈值为 10,则计算出的集群总量就为 30);而全局模式下配置的阈值等同于整个集群的总阈值。
ParamFlowRule
热点参数限流相关的集群配置与 FlowRule
相似。
集群规则配置方式
在集群流控的场景下,我们推荐使用动态规则源来动态地管理规则。
对于客户端,我们可以按照原有的方式来向 FlowRuleManager
和 ParamFlowRuleManager
注册动态规则源,例如:
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId, parser);
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
对于集群流控 token server,由于集群限流服务端有作用域(namespace)的概念,因此我们需要注册一个自动根据 namespace 生成动态规则源的 PropertySupplier:
// Supplier 类型:接受 namespace,返回生成的动态规则源,类型为 SentinelProperty<List<FlowRule>>
// ClusterFlowRuleManager 针对集群限流规则,ClusterParamFlowRuleManager 针对集群热点规则,配置方式类似
ClusterFlowRuleManager.setPropertySupplier(namespace -> {return new SomeDataSource(namespace).getProperty();
});
然后每当集群限流服务端 namespace set 产生变更时,Sentinel 会自动针对新加入的 namespace 生成动态规则源并进行自动监听,并删除旧的不需要的规则源。
集群限流客户端
要想使用集群限流功能,必须引入集群限流 client 相关依赖:
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-cluster-client-default</artifactId><version>1.8.0</version>
</dependency>
用户可以通过 API 将当前模式置为客户端模式:
http://<ip>:<port>/setClusterMode?mode=<xxx>
或者通过 ClusterStateManager API 手动指定模式:
// 指定当前身份为 Token Client
ClusterStateManager.applyState(ClusterStateManager.CLUSTER_CLIENT);
其中 mode 为 0 代表 client(ClusterStateManager.CLUSTER_CLIENT
),1 代表 server。设置成功后,若已有客户端的配置,集群限流客户端将会开启并连接远程的 token server。我们可以在 ~/logs/csp/sentinel-record.log
日志中查看连接的相关日志。
若集群限流客户端未进行配置,则用户需要对客户端进行基本的配置,比如指定集群限流 token server。我们提供了 API 进行配置:
http://<ip>:<port>/cluster/client/modifyConfig?data=<config>
其中 data 是 JSON 格式的配置项:
serverHost
: token server hostserverPort
: token server 端口requestTimeout
: 请求的超时时间(默认为 20 ms)
当然也可以通过动态配置源进行配置。集群限流 token client 共有两种配置:
- 客户端分配配置(
ClusterClientAssignConfig
),包括要连接的对端 token server 地址等相关信息。我们可以通过ClusterClientConfigManager
的registerServerAssignProperty
方法注册动态配置源。分配配置通常通过统一的分配表解析而来,可以参考 embedded 模式 demo。 - 客户端通信配置(
ClusterClientConfig
),包括通信的超时时长等配置。我们可以通过ClusterClientConfigManager
的registerClientConfigProperty
方法注册动态配置源。
配置源注册的相关逻辑可以置于 InitFunc
实现类中,并通过 SPI 注册,在 Sentinel 初始化时即可自动进行配置源加载监听。
若用户未引入集群限流 client 相关依赖,或者 client 未开启/连接失败/通信失败,则对于开启了集群模式的规则:
- 集群热点限流默认直接通过
- 普通集群限流会退化到 local 模式的限流,即在本地按照单机阈值执行限流检查
当 token client 与 server 之间的连接意外断开时,token client 会不断进行重试,每次重试的间隔时间以 n * 2000 ms
的形式递增。
集群限流服务端
要想使用集群限流服务端,必须引入集群限流 server 相关依赖:
<dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-cluster-server-default</artifactId><version>1.8.0</version>
</dependency>
启动方式
Sentinel 集群限流服务端有两种启动方式:
- 独立模式(Alone),即作为独立的 token server 进程启动,独立部署,隔离性好,但是需要额外的部署操作。独立模式适合作为 Global Rate Limiter 给集群提供流控服务。
- 嵌入模式(Embedded),即作为内置的 token server 与服务在同一进程中启动。在此模式下,集群中各个实例都是对等的,token server 和 client 可以随时进行转变,因此无需单独部署,灵活性比较好。但是隔离性不佳,需要限制 token server 的总 QPS,防止影响应用本身。嵌入模式适合某个应用集群内部的流控。
我们提供了 HTTP API 用于在 embedded 模式下转换集群流控身份:
http://<ip>:<port>/setClusterMode?mode=<xxx>
其中 mode 为 0
代表 client,1
代表 server,-1
代表关闭。注意应用端需要引入集群限流客户端或服务端的相应依赖。
在独立模式下,我们可以直接创建对应的 ClusterTokenServer
实例并在 main 函数中通过 start
方法启动 Token Server。
规则配置
见前面 规则配置 相关内容。
属性配置
我们推荐给集群限流服务端注册动态配置源来动态地进行配置。配置类型有以下几种:
- namespace set: 集群限流服务端的作用域(命名空间),用于指定该 token server 可以服务哪些应用或分组,嵌入模式下可以设置为自己的应用名。集群限流 client 在连接到 token server 后会上报自己的命名空间(默认为
project.name
配置的应用名),token server 会根据上报的命名空间名称统计连接数。 - transport config: 集群限流服务端通信相关配置,如 server port
- flow config: 集群限流服务端限流相关配置,如滑动窗口统计时长、格子数目、最大允许总 QPS等
我们可以通过 ClusterServerConfigManager
的各个 registerXxxProperty
方法来注册相关的配置源。
从 1.4.1 版本开始,Sentinel 支持给 token server 配置最大允许的总 QPS(maxAllowedQps
),用于对 Token Server 的资源使用进行限制,防止在嵌入模式下影响应用本身。
Token Server 分配配置
示例
sentinel-demo-cluster 提供了嵌入模式和独立模式的示例:
- sentinel-demo-cluster-server-alone:独立模式 Demo
- sentinel-demo-cluster-embedded:嵌入模式 Demo,以 Web 应用为示例,可以启动多个实例分别作为 Token Server 和 Token Client。数据源的相关配置可以参考 DemoClusterInitFunc。
注意:若在本地启动多个 Demo 示例,需要加上
-Dcsp.sentinel.log.use.pid=true
参数,否则控制台显示监控会不准确。
集群限流控制台
使用集群限流功能需要对 Sentinel 控制台进行相关的改造,推送规则时直接推送至配置中心,接入端引入 push 模式的动态数据源。可以参考 Sentinel 控制台(集群流控管理文档)。
同时云上版本 AHAS Sentinel 提供开箱即用的全自动托管集群流控能力,无需手动指定/分配 token server 以及管理连接状态,同时支持分钟小时级别流控、大流量低延时场景流控场景,同时支持 Istio/Envoy 场景的 Mesh 流控能力。
其它
若在生产环境使用集群限流,管控端还需要关注以下的问题:
- Token Server 自动管理、调度(分配/选举 Token Server)
- Token Server 高可用,在某个 server 不可用时自动 failover 到其它机器
集群流控日志
${log_dir}/sentinel-cluster-client.log
:Token Client 日志,会记录请求失败的信息
扩展接口设计
整体扩展架构
通用扩展接口
以下通用接口位于 sentinel-core
中:
TokenService
: 集群限流功能接口,server / client 均可复用ClusterTokenClient
: 集群限流功能客户端ClusterTokenServer
: 集群限流服务端接口EmbeddedClusterTokenServer
: 集群限流服务端接口(embedded 模式)
以下通用接口位于 sentinel-cluster-common-default
:
EntityWriter
EntityDecoder
Client 扩展接口
集群流控 Client 端通信相关扩展接口:
ClusterTransportClient
:集群限流通信客户端RequestEntityWriter
ResponseEntityDecoder
Server 扩展接口
集群流控 Server 端通信相关扩展接口:
ResponseEntityWriter
RequestEntityDecoder
集群流控 Server 端请求处理扩展接口:
RequestProcessor
: 请求处理接口 (request -> response)
Sentinel(六)之集群流控相关推荐
- Sentinel 发布里程碑版本,添加集群流控功能
为什么80%的码农都做不了架构师?>>> 自去年10月底发布GA版本后,Sentinel在近期发布了另一个里程碑版本v1.4(最新的版本号是v1.4.1),加入了开发者关注的集 ...
- html流控官网qq群,集群流控 · alibaba/Sentinel Wiki · GitHub
目录 介绍 为什么要使用集群流控呢?假设我们希望给某个用户限制调用某个 API 的总 QPS 为 50,但机器数可能很多(比如有 100 台).这时候我们很自然地就想到,找一个 server 来专门来 ...
- 如何利用 “集群流控” 保障微服务的稳定性?
作者:宿何 微服务的稳定性一直是开发者非常关注的话题.随着业务从单体架构向分布式架构演进以及部署方式的变化,服务之间的依赖关系变得越来越复杂,业务系统也面临着巨大的高可用挑战.应用高可用服务 AHAS ...
- Sentinel集群流控
- 《Reids 设计与实现》第十六章 集群(下)
<Reids 设计与实现>第十六章 集群(下) 文章目录 <Reids 设计与实现>第十六章 集群(下) 七.复制与故障转移 1.设置从节点 2.故障检测 3.故障转移 4.选 ...
- Redis 集群搭建(三):Docker 部署 Redis + Sentinel 高可用集群
Redis 集群搭建(三):Docker 部署 Redis + Sentinel 高可用集群 前言 建议 官方译文 什么是 Sentinel? Sentinel 优点 Redis 配置文件 maste ...
- Redis 哨兵(sentinel)模式集群配置(5.0.3版本)
一.准备工作 1.系统环境:centos6.4 2.服务器六台(1主5从): 192.168.1.161(master) 192.168.1.162(slave) 192.168.1.163(slav ...
- Sentinel高可用集群搭建
目录 一.前言 二.集群搭建 1.环境 2.配置文件介绍 3.实验中的sentinel配置 4.启动sentinel: 5.sentinel原理 6.运行测试 三.sentinel核心概念 1.Lea ...
- redis sentinel哨兵模式集群搭建教程
1.环境说明 我们将使用192.168.220.128.192.168.220.129两台机器搭建sentinel交叉主从为例 当前我们已在192.168.220.128上按redis安装教程安装了r ...
最新文章
- 他们创造了编程语言,他们是这个时代伟大的父亲
- 电脑病毒反抗杀毒软件的主要手段
- python 计算算术平方根
- mfc如何删除lineto画的_有哪些好用的板绘软件?衣服上的花纹怎么画?
- 鸿蒙有安卓内核吗,华为鸿蒙2.0可以替代安卓吗,华为鸿蒙2.0优势在哪
- 手语识别_如何使用转移学习进行手语识别
- QQ音乐全新上线HiRes高解析音质 听歌体验再升级
- 如何选型商业智能和分析平台,Gartner给了这些建议!
- uvalive 3938 Ray, Pass me the dishes! 线段树 区间合并
- Centos 7.0 的svn
- Userscript+ 去除广告
- 霍夫变换提取圆心坐标,并拟合直线
- win7系统音响没有声音的解决设置方法
- Hulu面试(或许待更)
- CNN应用之性别、年龄识别
- 第22章:针对Cloze Tests基于Attention机制的的MRC领域开山之作:Teaching Machines to Read and Comprehend架构设计及完整源码实现
- 学妹知道了这 19 条建议后,大学生活过得有滋有味
- Warshall算法的实现(两种方式)
- ExoPlayer播放器 开发者指南(官方权威指南译文)
- 突发奇想nico爬虫
热门文章
- leetcode-345-翻转字符串中的元音字母
- java pc计数器_java虚拟机-程序计数器PC Register
- leetcode300. 最长递增子序列
- [SpringBoot2]welcomefavicon
- Java 多线程:线程优先级
- [蓝桥杯2018决赛]迷宫与陷阱
- 计算机公共基础知识实验报告,20140902413 李雪瑞 计算机工程系实验报告345.docx...
- oracle秘钥到期,Oracle – 更新加入 – 非密钥保留表
- Oracle多租户体系,Oracle12C 多租户管理
- 数据结构---二叉平衡排序树的删除