3、 Sentinel 部署集群流控

Sentinel

1 部署sentinel

java -Dserver.port=8080 -jar  java -Dserver.port=18080 -jar 

 


Sentinel单机流控

流量控制(flow control),其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。

流量控制官方文档:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6

Sentinel的限流原理

  •     Sentinel以Bucket(桶)为单位记录一个时间窗口内的请求总数、异常总数、总耗时等指标数据。
  •     而一个Bucket可以是记录一秒内的数据,也可以是10毫秒内的数据,我们称这个时间窗口为Bucket的统计单位,由使用者自定义。

Sentinel 两种计算阈值的模式:

  •     集群总体模式:即限制整个集群内的某个资源的总体 qps 不超过此阈值。
  •     单机均摊模式:单机均摊模式下配置的阈值等同于单机能够承受的限额,token server 会根据连接数来计算总的阈值(比如独立模式下有 3个 client 连接到了 token server,然后配的单机均摊阈值为 10,则计算出的集群总量就为30),按照计算出的总的阈值来进行限制。这种方式根据当前的连接数实时计算总的阈值,对于机器经常进行变更的环境非常适合。

Sentinel限流的方式

  • 基于QPS/并发数的流量控制

  1. 并发线程数控制

  2. QPS流量控制  (直接拒绝 、 Warm Up  、 匀速排队)

  • 基于调用关系的流量控制

  1. 根据调用方限流

  2. 根据调用链路入口限流:链路限流

  3. 具有关系的资源流量控制:关联流量控制

 

spring 接入

1:依赖

<!--sentinel限流-->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
 <!-- <version>1.82.1.RELEASE</version>  -->
</dependency>

2  配置文件 application.properties

sprring.application.name=sentinelservice
server.port=9999
spring.cloud.sentinel.transport.dashboard=127.0.0.1:8080
spring.cloud.sentinel.eager=true

3 实现代码

@SpringBootApplication
@RestController
public class Application {
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);}
	@RequestMapping("/hello")
	@SentinelResource(value = "sayHello", fallback = "sayHellofail")
	public String sayHello() {
		return "Hello,World";
	}
	public String sayHellofail() {
		return "I'am sorry";
	}
}

4 访问查看,设置限流,触发服务降级


集群流控

文档:https://github.com/alibaba/Sentinel/wiki/%E9%9B%86%E7%BE%A4%E6%B5%81%E6%8E%A7

1  流控介绍

假如你的应用有多个实例,那么你设置了限流的规则之后,每一台应用的实例都会生效相同的流控规则

  • 假设集群中有 10 台机器,我们给每台机器设置单机限流阈值为 10 qps,理想情况下整个集群的限流阈值就为 100 qps。不过实际情况下路由到每台机器的流量可能会不均匀,会导致总量没有到的情况下某些机器就开始限流。
  • 每台单机实例只关心自己的阈值,对于整个系统的全局阈值大家都漠不关心,当我们希望为某个 api 设置一个总的 qps 时(就跟为 api 设置总的调用次数一样),那这种单机模式的限流就无法满足条件了。

2 原理

  • 集群限流的原理很简单,和单机限流一样,都需要对 qps 等数据进行统计,区别就在于单机版是在每个实例中进行统计,而集群版是有一个专门的实例进行统计。
  • 这个专门的用来统计数据的称为 Sentinel 的 token server,其他的实例作为 Sentinel 的 token client 会向 token server 去请求 token,如果能获取到 token,则说明当前的 qps 还未达到总的阈值,否则就说明已经达到集群的总阈值,当前实例需要被 block,如下图所示:

集群流控中共有两种身份:

  • 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 的相关逻辑

Sentinel 集群流控支持限流规则和热点规则两种规则,并支持两种形式的阈值计算方式:

  • 集群总体模式:即限制整个集群内的某个资源的总体 qps 不超过此阈值。
  • 单机均摊模式:单机均摊模式下配置的阈值等同于单机能够承受的限额,token server 会根据连接数来计算总的阈值(比如独立模式下有 3 个 client 连接到了 token server,然后配的单机均摊阈值为 10,则计算出的集群总量就为 30),按照计算出的总的阈值来进行限制。这种方式根据当前的连接数实时计算总的阈值,对于机器经常进行变更的环境非常适合。

集群流控规则

  • 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;

集群规则配置方式

推荐使用动态规则源来动态地管理规则

  • 对于客户端,我们可以按照原有的方式来向 FlowRuleManager ParamFlowRuleManager 注册动态规则源,例如
ReadableDataSource<String, List<FlowRule>> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId, parser);
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
  • 对于集群流控 token server,由于集群限流服务端有作用域(namespace)的概念,因此我们需要注册一个自动根据 namespace 生成动态规则源的 PropertySupplier:   然后每当集群限流服务端 namespace set 产生变更时,Sentinel 会自动针对新加入的 namespace 生成动态规则源并进行自动监听,并删除旧的不需要的规则源。
// Supplier 类型:接受 namespace,返回生成的动态规则源,类型为 SentinelProperty<List<FlowRule>>
// ClusterFlowRuleManager 针对集群限流规则,ClusterParamFlowRuleManager 针对集群热点规则,配置方式类似
ClusterFlowRuleManager.setPropertySupplier(namespace -> {
    return new SomeDataSource(namespace).getProperty();
});

集群限流客户端

  • 必须引入集群限流 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>

当然也可以通过动态配置源进行配置。集群限流 token client 共有两种配置:

  • 客户端分配配置(ClusterClientAssignConfig),包括要连接的对端 token server 地址等相关信息。我们可以通过 ClusterClientConfigManagerregisterServerAssignProperty 方法注册动态配置源。分配配置通常通过统一的分配表解析而来,可以参考 embedded 模式 demo。
  • 客户端通信配置(ClusterClientConfig),包括通信的超时时长等配置。我们可以通过 ClusterClientConfigManagerregisterClientConfigProperty 方法注册动态配置源。

配置源注册的相关逻辑可以置于 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

规则配置

属性配置

集群限流服务端注册动态配置源来动态地进行配置。配置类型有以下几种 ( 我们可以通过 ClusterServerConfigManager 的各个 registerXxxProperty 方法来注册相关的配置源)

  • namespace set: 集群限流服务端的作用域(命名空间),用于指定该 token server 可以服务哪些应用或分组,嵌入模式下可以设置为自己的应用名。集群限流 client 在连接到 token server 后会上报自己的命名空间(默认为 project.name 配置的应用名),token server 会根据上报的命名空间名称统计连接数。
  • transport config: 集群限流服务端通信相关配置,如 server port
  • flow config: 集群限流服务端限流相关配置,如滑动窗口统计时长、格子数目、最大允许总 QPS等

从 1.4.1 版本开始,Sentinel 支持给 token server 配置最大允许的总 QPS(maxAllowedQps),用于对 Token Server 的资源使用进行限制,防止在嵌入模式下影响应用本身。

Token Server 分配配置

 


参考文档: Sentinel实现限流  https://blog.csdn.net/weixin_40990818/article/details/107617857

                   Sentinel集群限流  https://blog.csdn.net/fedorafrog/article/details/114793103

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值