java -Dserver.port=8080 -jar java -Dserver.port=18080 -jar
流量控制(flow control),其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
流量控制官方文档:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6
Sentinel的限流原理
Sentinel 两种计算阈值的模式:
Sentinel限流的方式
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
sprring.application.name=sentinelservice
server.port=9999
spring.cloud.sentinel.transport.dashboard=127.0.0.1:8080
spring.cloud.sentinel.eager=true
@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";
}
}
文档:https://github.com/alibaba/Sentinel/wiki/%E9%9B%86%E7%BE%A4%E6%B5%81%E6%8E%A7
假如你的应用有多个实例,那么你设置了限流的规则之后,每一台应用的实例都会生效相同的流控规则
集群流控中共有两种身份:
Sentinel 1.4.0 开始引入了集群流控模块,主要包含以下几部分:
sentinel-cluster-common-default
: 公共模块,包含公共接口和实体sentinel-cluster-client-default
: 默认集群流控 client 模块,使用 Netty 进行通信,提供接口方便序列化协议扩展sentinel-cluster-server-default
: 默认集群流控 server 模块,使用 Netty 进行通信,提供接口方便序列化协议扩展;同时提供扩展接口对接规则判断的具体实现(TokenService
),默认实现是复用 sentinel-core
的相关逻辑Sentinel 集群流控支持限流规则和热点规则两种规则,并支持两种形式的阈值计算方式:
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> flowRuleDataSource = new NacosDataSource<>(remoteAddress, groupId, dataId, parser);
FlowRuleManager.register2Property(flowRuleDataSource.getProperty());
// Supplier 类型:接受 namespace,返回生成的动态规则源,类型为 SentinelProperty>
// ClusterFlowRuleManager 针对集群限流规则,ClusterParamFlowRuleManager 针对集群热点规则,配置方式类似
ClusterFlowRuleManager.setPropertySupplier(namespace -> {
return new SomeDataSource(namespace).getProperty();
});
com.alibaba.csp
sentinel-cluster-client-default
1.8.0
// 指定当前身份为 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://:/cluster/client/modifyConfig?data=
当然也可以通过动态配置源进行配置。集群限流 token client 共有两种配置:
ClusterClientAssignConfig
),包括要连接的对端 token server 地址等相关信息。我们可以通过 ClusterClientConfigManager
的 registerServerAssignProperty
方法注册动态配置源。分配配置通常通过统一的分配表解析而来,可以参考 embedded 模式 demo。ClusterClientConfig
),包括通信的超时时长等配置。我们可以通过 ClusterClientConfigManager
的 registerClientConfigProperty
方法注册动态配置源。配置源注册的相关逻辑可以置于 InitFunc
实现类中,并通过 SPI 注册,在 Sentinel 初始化时即可自动进行配置源加载监听。
若用户未引入集群限流 client 相关依赖,或者 client 未开启/连接失败/通信失败,则对于开启了集群模式的规则:
当 token client 与 server 之间的连接意外断开时,token client 会不断进行重试,每次重试的间隔时间以 n * 2000 ms
的形式递增。
server 相关依赖:
com.alibaba.csp
sentinel-cluster-server-default
1.8.0
Sentinel 集群限流服务端有两种启动方式:
提供了 HTTP API 用于在 embedded 模式下转换集群流控身份:
http://:/setClusterMode?mode=
其中 mode 为 0
代表 client,1
代表 server,-1
代表关闭。注意应用端需要引入集群限流客户端或服务端的相应依赖。
在独立模式下,我们可以直接创建对应的 ClusterTokenServer
实例并在 main 函数中通过 start
方法启动 Token Server
集群限流服务端注册动态配置源来动态地进行配置。配置类型有以下几种 ( 我们可以通过 ClusterServerConfigManager
的各个 registerXxxProperty
方法来注册相关的配置源)
project.name
配置的应用名),token server 会根据上报的命名空间名称统计连接数。从 1.4.1 版本开始,Sentinel 支持给 token server 配置最大允许的总 QPS(maxAllowedQps
),用于对 Token Server 的资源使用进行限制,防止在嵌入模式下影响应用本身。
参考文档: Sentinel实现限流 https://blog.csdn.net/weixin_40990818/article/details/107617857
Sentinel集群限流 https://blog.csdn.net/fedorafrog/article/details/114793103