Sentinel 是阿里巴巴开源的,面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统自适应保护等多个维度来帮助开发者保障微服务的稳定性。Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀、冷启动、消息削峰填谷、集群流量控制、实时熔断下游不可用服务等,是保障微服务高可用的利器,原生支持 Java/Go/C++ 等多种语言,而且提供 Istio/Envoy/SOFA MOSN 全局流控支持来为 Service Mesh 提供高可用防御的能力。html
近期,Sentinel Go 0.4.0 正式发布,带来了热点参数流控特性,能够自动识别统计传入参数中的“热点”参数值并分别进行流控,对于防刷、热点商品访问频次控制等场景很是有用,是高可用流量防御中重要的一环。下面咱们来了解一下热点参数流控的场景和原理。git
流量是随机的,不可预测的。为了防止被大流量打垮,咱们一般会对核心接口配置限流规则,但有的场景下配置普通的流控规则是不够的。咱们来看这样一种场景——大促峰值的时候,老是会有很多“热点”商品,这些热点商品的瞬时访问量很是高。通常状况下,咱们能够事先预测一波热点商品,并对这些商品信息进行缓存“预热”,以便在出现大量访问时能够快速返回而不会都打到 DB 上。但每次大促都会涌现出一些“黑马”商品,这些“黑马”商品是咱们没法事先预测的,没有被预热。当这些“黑马”商品访问量激增时,大量的请求会击穿缓存,直接打到 DB 层,致使 DB 访问缓慢,挤占正常商品请求的资源池,最后可能会致使系统挂掉。这时候,利用 Sentinel 的热点参数流量控制能力,自动识别热点参数并控制每一个热点值的访问 QPS 或并发量,能够有效地防止过“热”的参数访问挤占正常的调用资源。github
再好比有的场景下咱们但愿限制每一个用户调用某个 API 的频率,将 API 名称+userId 做为埋点资源名显然是不合适的。这时候咱们能够在给 API 埋点的时候经过 WithArgs(xxx)
将 userId 做为参数传入到 API 埋点中,而后配置热点规则便可针对每一个用户分别限制调用频率;同时,Sentinel 也支持针对某些具体值单独配置限流值,进行精细化流控。golang
热点参数埋点/规则示例:api
// 埋点示例 e, b := sentinel.Entry("my-api", sentinel.WithArgs(rand.Uint32()%3000, "sentinel", uuid.New().String())) // 规则示例 _, err = hotspot.LoadRules([]*hotspot.Rule{ { Resource: "my-api", MetricType: hotspot.QPS, // 请求量模式 ControlBehavior: hotspot.Reject, ParamIndex: 0, // 参数索引,0 即为第一个参数 Threshold: 50, // 针对每一个热点参数值的阈值 BurstCount: 0, DurationInSec: 1, // 统计窗口时长,这里为 1s SpecificItems: map[hotspot.SpecificValue]int64{ // 支持针对某个具体值单独配置限流值,好比这里针对数值 9 限制请求量=0(不容许经过) {ValKind: hotspot.KindInt, ValStr: "9"}: 0, }, }, })
像其余规则同样,热点流控规则一样支持经过动态数据源进行动态配置。缓存
Sentinel Go 提供的 RPC 框架整合模块(如 Dubbo、gRPC)均会自动将 RPC 调用的参数列表附带在埋点中,用户能够直接针对相应的参数位置配置热点流控规则。目前热点规则仅支持基本类型和字符串类型,后续社区会进一步进行完善,支持更多的类型。架构
Sentinel Go 的热点流量控制基于缓存淘汰机制+令牌桶机制实现。Sentinel 经过淘汰机制(如 LRU、LFU、ARC 策略等)来识别热点参数,经过令牌桶机制来控制每一个热点参数的访问量。目前 0.4.0 版本采用 LRU 策略统计热点参数,在后续的版本中社区会引入更多的缓存淘汰机制来适配不一样的场景。并发
在服务提供方(Service Provider)的场景下,咱们须要保护服务提供方不被流量洪峰打垮。咱们一般根据服务提供方的服务能力进行流量控制,或针对特定的服务调用方进行限制。为了保护服务提供方不被激增的流量拖垮影响稳定性,咱们能够结合前期的容量评估,经过 Sentinel 配置 QPS 模式的流控规则,当每秒的请求量超过设定的阈值时,会自动拒绝多余的请求。同时能够结合热点参数流控进行细粒度的流量防御。框架
在服务调用端(Service Consumer)的场景下,咱们须要保护服务调用方不被不稳定的依赖服务拖垮。借助 Sentinel 的信号量隔离策略(并发数流控规则),限制某个服务调用的并发量,防止大量慢调用挤占正常请求的资源;同时,借助熔断降级规则,当异常比率或业务慢调用比例超过某个阈值后将调用自动熔断,直到一段时间事后再尝试恢复。熔断期间咱们能够提供默认的处理逻辑(fallback),熔断期间的调用都会返回 fallback 的结果,而不会再去尝试本已很是不稳定的服务。须要注意的是,即便服务调用方引入了熔断降级机制,咱们仍是须要在 HTTP 或 RPC 客户端配置请求超时时间,来作一个兜底的保护。分布式
在一些请求突刺的场景中,好比 MQ 客户端消费消息的场景,咱们可能不但愿将多余的消息直接拒绝(重投),而是让这些过量的消息排队逐步处理。这就是“削峰填谷”的场景。咱们能够利用 Sentinel 流控规则中的“匀速+排队等待”控制效果来处理这种场景,以固定的间隔时间让请求经过,超出预设量的请求排队等待。这种方式适合用于请求以突刺状来到,这个时候咱们不但愿一会儿把全部的请求都经过,这样可能会把系统压垮;同时咱们也期待系统以稳定的速度,逐步处理这些请求,以起到“削峰填谷”的效果,而不是直接拒绝全部多余的请求。
同时 Sentinel Go 还提供 全局维度的系统自适应保护能力,结合系统的 Load、CPU 使用率以及服务的入口 QPS、响应时间和并发量等几个维度的监控指标,经过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽量跑在最大吞吐量的同时保证系统总体的稳定性。系统规则能够做为整个服务的一个兜底防御策略,保障服务不挂。
Sentinel Go 版本正在快速演进中,咱们很是欢迎感兴趣的开发者参与贡献,一块儿来主导将来版本的演进。Sentinel Go 版本的演进离不开社区的贡献。若您有意愿参与贡献,欢迎联系咱们加入 Sentinel 贡献小组一块儿成长(Sentinel 开源讨论钉钉群:30150716)。咱们会按期给活跃贡献者寄送小礼品,核心贡献者能够提名为 committer,一块儿主导社区的演进。同时,也欢迎你们经过 AHAS Sentinel 控制台 来快速体验 Sentinel 的能力。Now let's start hacking!