阿里双11同款流控降级组件 Sentinel Go简介
作者 | 赵奕豪(宿何) Sentinel 开源项目负责人
前言
大促时瞬间洪峰流量导致系统超出最大负载,load 飙高,系统崩溃导致用户无法下单。
“黑马”热点商品击穿缓存,DB 被打垮,挤占正常流量。
调用端被不稳定第三方服务拖垮,线程池被占满,调用堆积,导致整个调用链路卡死。
Sentinel 介绍
是阿里巴巴开源的,面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统自适应保护等多个维度来帮助开发者保障微服务的稳定性。Sentinel 承接了阿里巴巴近 10 年的 双11 大促流量的核心场景,例如秒杀、冷启动、消息削峰填谷、集群流量控制、实时熔断下游不可用服务等,是保障微服务高可用的利器,原生支持 Java/Go/C++ 等多种语言,并且提供 Istio/Envoy 全局流控支持来为 Service Mesh 提供高可用防护的能力。
就在近期,正式发布,标志着 Go 版本正式进入生产可用阶段。Sentinel Go 1.0 版本对齐了 Java 版本核心的高可用防护和容错能力,包括限流、流量整形、并发控制、熔断降级、系统自适应保护、热点防护等特性。同时 Go 版本已覆盖主流开源生态,提供了 Gin、gRPC、go-micro、dubbo-go 等,并提供了 etcd、Nacos、Consul 等。Sentinel Go 也在朝着云原生的方向不断演进,1.0 版本中也进行了一些云原生方面的探索,包括 Kubernetes CRD data-source, Kubernetes HPA 等。对于 Sentinel Go 版本而言,我们期望的流控场景并不局限于微服务应用本身。云原生基础组件中 Go 语言生态占比较高,而这些云原生组件很多时候又缺乏细粒度、自适应的保护与容错机制,这时候就可以结合组件的一些扩展机制,利用 Sentinel Go 来保护自身的稳定性。
高可用防护的核心场景
1. 流量控制与调配
_, err = flow.LoadRules([]*flow.Rule{
{
Resource: "some-service", // 埋点资源名
Count: 10, // 阈值为 10,默认为秒级维度统计,即该请求单机每秒不超过 10 次
ControlBehavior: flow.Reject, // 控制效果为直接拒绝,不控制请求之间的时间间隔,不排队
},
})
2. Warm-Up 预热流控
3. 并发控制与熔断降级
并发控制(isolation 模块):作为一种轻量级隔离的手段,控制某些调用的并发数(即正在进行的数目),防止过多的慢调用挤占正常的调用。 熔断降级(circuitbreaker 模块):对不稳定的弱依赖调用进行自动熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。
4. 热点防护
流量是随机的,不可预测的。为了防止被大流量打垮,我们通常会对核心接口配置限流规则,但有的场景下配置普通的流控规则是不够的。我们来看这样一种场景——大促峰值的时候,总是会有不少“热点”商品,这些热点商品的瞬时访问量非常高。一般情况下,我们可以事先预测一波热点商品,并对这些商品信息进行缓存“预热”,以便在出现大量访问时可以快速返回而不会都打到 DB 上。但每次大促都会涌现出一些“黑马”商品,这些“黑马”商品是我们无法事先预测的,没有被预热。当这些“黑马”商品访问量激增时,大量的请求会击穿缓存,直接打到 DB 层,导致 DB 访问缓慢,挤占正常商品请求的资源池,最后可能会导致系统挂掉。这时候,利用 Sentinel 的,自动识别热点参数并控制每个热点值的访问 QPS 或并发量,可以有效地防止过“热”的参数访问挤占正常的调用资源。
WithArgs(xxx)
将 userId 作为参数传入到 API 埋点中,然后配置热点规则即可针对每个用户分别限制调用频率;同时,Sentinel 也支持针对某些具体值单独配置限流值,进行精细化流控。像其他规则一样,热点流控规则同样支持通过动态数据源进行动态配置。5. 系统自适应保护
云原生探索
1. Kubernetes CRD data-source
在生产环境中我们一般都需要通过配置中心来动态管理各种规则配置。在 Kubernetes 集群中,我们可以天然利用 Kubernetes CRD 的方式来管理应用的 Sentinel 规则。在 Go 1.0.0 版本中社区提供了基本的 Sentinel 规则 CRD 抽象以及相应的。用户只需要先导入 Sentinel 规则 CRD 定义文件,接入 Sentinel 时注册对应的 data-source,然后按照 CRD 定义的格式编写 YAML 配置并 kubectl apply 到对应的 namespace 下即可实现动态配置规则。以下是一个流控规则的示例:
apiVersion: datasource.sentinel.io/v1alpha1
kind: FlowRules
metadata:
name: foo-sentinel-flow-rules
spec:
rules:
- resource: simple-resource
threshold: 500
- resource: something-to-smooth
threshold: 100
controlBehavior: Throttling
maxQueueingTimeMs: 500
- resource: something-to-warmup
threshold: 200
tokenCalculateStrategy: WarmUp
controlBehavior: Reject
warmUpPeriodSec: 30
warmUpColdFactor: 3
2. Service Mesh
Service Mesh 是微服务向云原生演进的趋势之一。在 Service Mesh 架构下,一些服务治理和策略控制的能力都逐渐下沉到了 data plane 层。去年 Sentinel 社区在 Java 1.7.0 版本里面做了一些尝试,提供了 Envoy Global Rate Limiting gRPC Service 的实现 ——,借助 Sentinel 集群限流 token server 来为 Envoy 服务网格提供集群流量控制的能力。今年随着 Sentinel Go 版本的诞生,社区与更多的 Service Mesh 产品开展合作、整合。我们与蚂蚁的 MOSN 社区进行共建,在 MOSN Mesh 中原生支持了 Sentinel Go 的流控降级能力,同时也已在蚂蚁内部落地。社区也在探索更为通用的方案,如利用 Istio 的 Envoy WASM 扩展机制实现 Sentinel 插件,让 Istio/Envoy 服务网格可以借助 Sentinel 原生的流控降级与自适应保护的能力来保障整个集群服务的稳定性。
3. Kubernetes HPA based on Sentinel metrics
保障服务稳定性的方法多种多样,除了各种规则对流量进行“控制”之外,“弹性”也是一种思路。对于部署在 Kubernetes 中的应用来说,可以利用 Kubernetes HPA 能力进行对服务进行水平扩缩容。HPA 默认支持多种系统指标,并且支持自定义指标统计。目前我们已经在阿里云 Kubernetes 容器服务上结合支持基于服务的平均 QPS、响应时间等作为条件进行弹性伸缩。社区也正在这一块做一些尝试,将一些 Sentinel 的服务级别的指标统计(通过量,拒绝量,响应时间等)通过 Prometheus 或 OpenTelemetry 等标准方式透出,并适配到 Kubernetes HPA 中。
Let's start hacking!
本次 GA 我们也新加入了两位给力的 committer —— 和 @luckyxiaoqiang,两位在 1.0 版本的演进带来了 Warm Up 流控、Nacos 动态数据源以及一系列功能改进和性能优化,非常积极地帮助社区答疑解惑以及 review 代码。恭喜两位!社区在未来版本中也会朝着云原生和自适应智能化的方向不断探索和演进,也欢迎更多的同学加入贡献小组,一起参与 Sentinel 未来的演进,创造无限可能。我们鼓励任何形式的贡献,包括但不限于:
bug fix
new features/improvements
dashboard
document/website
test cases
Sentinel Go repo: https://github.com/alibaba/sentinel-golang 企业用户欢迎进行登记: https://github.com/alibaba/Sentinel/issues/18 Sentinel 阿里云企业版: https://ahas.console.aliyun.com/
技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。