静态网页建站,郑州新密网站建设,沧州做网站的公司排名,管理系统网站模板下载转载自 集群流控
介绍
为什么要使用集群流控呢#xff1f;假设我们希望给某个用户限制调用某个 API 的总 QPS 为 50#xff0c;但机器数可能很多#xff08;比如有 100 台#xff09;。这时候我们很自然地就想到#xff0c;找一个 server 来专门来统计总的调用量#…转载自 集群流控
介绍
为什么要使用集群流控呢假设我们希望给某个用户限制调用某个 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 代表全局唯一的规则 IDSentinel 集群限流服务端通过此 ID 来区分各个规则因此务必保持全局唯一。一般 flowId 由统一的管控端进行分配或写入至 DB 时生成。thresholdType 代表集群限流阈值模式。其中单机均摊模式下配置的阈值等同于单机能够承受的限额token server 会根据客户端对应的 namespace默认为 project.name 定义的应用名下的连接数来计算总的阈值比如独立模式下有 3 个 client 连接到了 token server然后配的单机均摊阈值为 10则计算出的集群总量就为 30而全局模式下配置的阈值等同于整个集群的总阈值。
ParamFlowRule 热点参数限流相关的集群配置与 FlowRule 相似。
集群规则配置方式
在集群流控的场景下我们推荐使用动态规则源来动态地管理规则。
对于客户端我们可以按照原有的方式来向 FlowRuleManager 和 ParamFlowRuleManager 注册动态规则源例如
ReadableDataSourceString, ListFlowRule flowRuleDataSource new NacosDataSource(remoteAddress, groupId, dataId, parser);
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
对于集群流控 token server由于集群限流服务端有作用域namespace的概念因此我们需要注册一个自动根据 namespace 生成动态规则源的 PropertySupplier:
// Supplier 类型接受 namespace返回生成的动态规则源类型为 SentinelPropertyListFlowRule
// ClusterFlowRuleManager 针对集群限流规则ClusterParamFlowRuleManager 针对集群热点规则配置方式类似
ClusterFlowRuleManager.setPropertySupplier(namespace - {return new SomeDataSource(namespace).getProperty();
});
然后每当集群限流服务端 namespace set 产生变更时Sentinel 会自动针对新加入的 namespace 生成动态规则源并进行自动监听并删除旧的不需要的规则源。
集群限流客户端
要想使用集群限流功能必须引入集群限流 client 相关依赖
dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-cluster-client-default/artifactIdversion1.8.0/version
/dependency
用户可以通过 API 将当前模式置为客户端模式
http://ip:port/setClusterMode?modexxx
或者通过 ClusterStateManager API 手动指定模式
// 指定当前身份为 Token Client
ClusterStateManager.applyState(ClusterStateManager.CLUSTER_CLIENT);
其中 mode 为 0 代表 clientClusterStateManager.CLUSTER_CLIENT1 代表 server。设置成功后若已有客户端的配置集群限流客户端将会开启并连接远程的 token server。我们可以在 ~/logs/csp/sentinel-record.log 日志中查看连接的相关日志。
若集群限流客户端未进行配置则用户需要对客户端进行基本的配置比如指定集群限流 token server。我们提供了 API 进行配置
http://ip:port/cluster/client/modifyConfig?dataconfig
其中 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 相关依赖
dependencygroupIdcom.alibaba.csp/groupIdartifactIdsentinel-cluster-server-default/artifactIdversion1.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?modexxx
其中 mode 为 0 代表 client1 代表 server-1 代表关闭。注意应用端需要引入集群限流客户端或服务端的相应依赖。
在独立模式下我们可以直接创建对应的 ClusterTokenServer 实例并在 main 函数中通过 start 方法启动 Token Server。
规则配置
见前面 规则配置 相关内容。
属性配置
我们推荐给集群限流服务端注册动态配置源来动态地进行配置。配置类型有以下几种
namespace set: 集群限流服务端的作用域命名空间用于指定该 token server 可以服务哪些应用或分组嵌入模式下可以设置为自己的应用名。集群限流 client 在连接到 token server 后会上报自己的命名空间默认为 project.name 配置的应用名token server 会根据上报的命名空间名称统计连接数。transport config: 集群限流服务端通信相关配置如 server portflow config: 集群限流服务端限流相关配置如滑动窗口统计时长、格子数目、最大允许总 QPS等
我们可以通过 ClusterServerConfigManager 的各个 registerXxxProperty 方法来注册相关的配置源。
从 1.4.1 版本开始Sentinel 支持给 token server 配置最大允许的总 QPSmaxAllowedQps用于对 Token Server 的资源使用进行限制防止在嵌入模式下影响应用本身。
Token Server 分配配置 示例
sentinel-demo-cluster 提供了嵌入模式和独立模式的示例
sentinel-demo-cluster-server-alone独立模式 Demosentinel-demo-cluster-embedded嵌入模式 Demo以 Web 应用为示例可以启动多个实例分别作为 Token Server 和 Token Client。数据源的相关配置可以参考 DemoClusterInitFunc。注意若在本地启动多个 Demo 示例需要加上 -Dcsp.sentinel.log.use.pidtrue 参数否则控制台显示监控会不准确。 集群限流控制台
使用集群限流功能需要对 Sentinel 控制台进行相关的改造推送规则时直接推送至配置中心接入端引入 push 模式的动态数据源。可以参考 Sentinel 控制台集群流控管理文档。
同时云上版本 AHAS Sentinel 提供开箱即用的全自动托管集群流控能力无需手动指定/分配 token server 以及管理连接状态同时支持分钟小时级别流控、大流量低延时场景流控场景同时支持 Istio/Envoy 场景的 Mesh 流控能力。
其它
若在生产环境使用集群限流管控端还需要关注以下的问题
Token Server 自动管理、调度分配/选举 Token ServerToken Server 高可用在某个 server 不可用时自动 failover 到其它机器
集群流控日志
${log_dir}/sentinel-cluster-client.logToken Client 日志会记录请求失败的信息
扩展接口设计
整体扩展架构 通用扩展接口
以下通用接口位于 sentinel-core 中
TokenService: 集群限流功能接口server / client 均可复用ClusterTokenClient: 集群限流功能客户端ClusterTokenServer: 集群限流服务端接口EmbeddedClusterTokenServer: 集群限流服务端接口embedded 模式
以下通用接口位于 sentinel-cluster-common-default:
EntityWriterEntityDecoder
Client 扩展接口
集群流控 Client 端通信相关扩展接口
ClusterTransportClient集群限流通信客户端RequestEntityWriterResponseEntityDecoder
Server 扩展接口
集群流控 Server 端通信相关扩展接口
ResponseEntityWriterRequestEntityDecoder
集群流控 Server 端请求处理扩展接口
RequestProcessor: 请求处理接口 (request - response)