Sentinel(分布式系统的流量防卫兵)
随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护等多个维度来帮助您保障微服务的稳定性。
- 查看机器列表以及健康情况:收集Sentinel客户端发送的心跳包,用于判断机器是否在线。
- 监控 (单机和集群聚合):通过Sentinel客户端暴露的监控API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。
- 规则管理和推送:统一管理推送规则。
- 鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。
启动控制台
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar
工作流程
SlotChain(责任链)
- NodeSelectorSlot 负责收集资源的路径,并将这些资源的调用路径,以树状结构存储起来,用于根据调用路径来限流降级;
- ClusterBuilderSlot 则用于存储资源的统计信息以及调用者信息,例如该资源的 RT, QPS, thread count 等等,这些信息将用作为多维度限流,降级的依据;
- StatistcSlot 则用于记录,统计不同纬度的 runtime 信息;
- FlowSlot 则用于根据预设的限流规则,以及前面 slot 统计的状态,来进行限流;
- AuthorizationSlot 则根据黑白名单,来做黑白名单控制;
- DegradeSlot 则通过统计信息,以及预设的规则,来做熔断降级;
- SystemSlot 则通过系统的状态,例如 load1 等,来控制总的入口流量;
GatewayFlowRule(网关流量控制规则)字段说明:
- resource:资源名,限流规则的作用对象
- resourceMode:资源限流维度(Route、自定义API)
- limitApp:区分调用来源,默认default
- grade:限流指标(QPS、线程数)
- count:限流阈值
- strategy:判断策略(资源本身、关联资源)
- controlBehavior:流量整形的控制行为(直接拒绝、匀速排队)
- clusterMode:集群模式
- maxQueueingTimeoutMs:匀速排队模式下的最长排队时间
- burst:应对突发请求时额外允许的请求数目
- paramItem:参数限流配置
- parseStrategy:从请求中提取参数的策略(IP、Host、Header、URL Param)
- fieldName:parseStrategy为Header或URL Param时,指定对应的header名称或URL参数名称
- pattern:参数值的匹配模式
- matchStrategy:参数值的匹配策略(精准匹配、子串匹配、正则匹配)
GatewayRuleManager.loadRules(rules) 手动加载网关规则,或通过 GatewayRuleManager.register2Property(property)注册动态规则源动态推送(推荐方式)
树状结构
curl http://localhost:8719/tree?type=root
Example
日志
拦截详情日志:
${user_home}/logs/csp/sentinel-block.log
秒级监控日志:
${user_home}/logs/csp/${app_name}-${pid}-metrics.log
业务日志:
${user_home}/logs/csp/sentinel-record.log.xxx
集群限流日志:
${log_dir}/sentinel-cluster-client.log
Endpoint http://127.0.0.1:18083/actuator/sentinel
Spring Cloud Alibaba Sentinel 提供了这些配置选项
|===
|配置项 |含义 |默认值
|spring.application.name or project.name|Sentinel项目名|
|spring.cloud.sentinel.enabled|Sentinel自动化配置是否生效|true
|spring.cloud.sentinel.eager|是否提前触发 Sentinel 初始化|false
|spring.cloud.sentinel.transport.port|应用与Sentinel控制台交互的端口,应用本地会起一个该端口占用的HttpServer|8719
|spring.cloud.sentinel.transport.dashboard|Sentinel 控制台地址|
|spring.cloud.sentinel.transport.heartbeat-interval-ms|应用与Sentinel控制台的心跳间隔时间|
|spring.cloud.sentinel.transport.client-ip|此配置的客户端IP将被注册到 Sentinel Server 端|
|spring.cloud.sentinel.filter.order|Servlet Filter的加载顺序。Starter内部会构造这个filter|Integer.MIN_VALUE
|spring.cloud.sentinel.filter.url-patterns|数据类型是数组。表示Servlet Filter的url pattern集合|/*
|spring.cloud.sentinel.filter.enabled|Enable to instance CommonFilter|true
|spring.cloud.sentinel.metric.charset|metric文件字符集|UTF-8
|spring.cloud.sentinel.metric.file-single-size|Sentinel metric 单个文件的大小|
|spring.cloud.sentinel.metric.file-total-count|Sentinel metric 总文件数量|
|spring.cloud.sentinel.log.dir|Sentinel 日志文件所在的目录|
|spring.cloud.sentinel.log.switch-pid|Sentinel 日志文件名是否需要带上pid|false
|spring.cloud.sentinel.servlet.block-page| 自定义的跳转 URL,当请求被限流时会自动跳转至设定好的 URL |
|spring.cloud.sentinel.flow.cold-factor| github.com/alibaba/Sen…
%E5%86%B7%E5%90%AF%E5%8A%A8[冷启动因子] |3
|spring.cloud.sentinel.zuul.order.pre| SentinelZuulPreFilter 的 order | 10000
|spring.cloud.sentinel.zuul.order.post| SentinelZuulPostFilter 的 order | 1000
|spring.cloud.sentinel.zuul.order.error| SentinelZuulErrorFilter 的 order | -1
|spring.cloud.sentinel.scg.fallback.mode| Spring Cloud Gateway 熔断后的响应模式(选择 redirect or response) |
|spring.cloud.sentinel.scg.fallback.redirect| Spring Cloud Gateway 响应模式为 'redirect' 模式对应的重定向 URL |
|spring.cloud.sentinel.scg.fallback.response-body| Spring Cloud Gateway 响应模式为 'response' 模式对应的响应内容 |
|spring.cloud.sentinel.scg.fallback.response-status| Spring Cloud Gateway 响应模式为 'response' 模式对应的响应码 | 429
|spring.cloud.sentinel.scg.fallback.content-type| Spring Cloud Gateway 响应模式为 'response' 模式对应的 content-type | application/json
|===
Sentinel RulesWebFluxController.java
package com.light.gateway.controller;
@RestController
public class RulesWebFluxController {
@GetMapping("/api")
public Mono<Set<ApiDefinition>> apiRules() {
return Mono.just(GatewayApiDefinitionManager.getApiDefinitions());
}
@GetMapping("/gateway")
public Mono<Set<GatewayFlowRule>> apiGateway() {
return Mono.just(GatewayRuleManager.getRules());
}
@GetMapping("/system")
public Mono<List<SystemRule>> systemGateway() {
return Mono.just(SystemRuleManager.getRules());
}
@GetMapping("/flow")
public Mono<List<FlowRule>> apiFlow() {
return Mono.just(FlowRuleManager.getRules());
}
@GetMapping("/param-flow")
public Mono<List<ParamFlowRule>> paramApiFlow() {
return Mono.just(ParamFlowRuleManager.getRules());
}
}
线程池与信号量区别
- 线程池技术,适合绝大多数场景,比如说我们对依赖服务的网络请求的调用和访问、需要对调用的 timeout 进行控制(捕捉 timeout 超时异常)。
- 信号量技术,适合说你的访问不是对外部依赖的访问,而是对内部的一些比较复杂的业务逻辑的访问,并且系统内部的代码,其实不涉及任何的网络请求,那么只要做信号量的普通限流就可以了,因为不需要去捕获 timeout 类似的问题。
参考
- 社区用户的一些扩展和解决方案: github.com/sentinel-gr…
- Sentinel 控制台(集群流控管理):github.com/alibaba/Sen…
- Sentinel 动态规则扩展:github.com/alibaba/Sen…
- Spring Cloud Alibaba之服务容错组件 - Sentinel [规则持久化篇]:www.jianshu.com/p/8ca2db6a0…
- Sentinel Dashboard 多数据源版本之Nacos示例代码:github.com/finefuture/…
- 社区用户的一些扩展和解决方案 github.com/sentinel-gr…
- 限流降级神器-哨兵(sentinel)原理分析 mp.weixin.qq.com/s/7_pCkamNv…
- 阿里巴巴开源限流降级神器Sentinel大规模生产级应用实践 mp.weixin.qq.com/s/AjHCUmygT…
- sentinelguard.io/zh-cn/index…
- github.com/alibaba/Sen…
- github.com/sentinel-gr…