Sentinel入门

165 阅读5分钟

Sentinel(分布式系统的流量防卫兵)

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护等多个维度来帮助您保障微服务的稳定性。

  • 查看机器列表以及健康情况:收集Sentinel客户端发送的心跳包,用于判断机器是否在线。
  • 监控 (单机和集群聚合):通过Sentinel客户端暴露的监控API,定期拉取并且聚合应用监控信息,最终可以实现秒级的实时监控。
  • 规则管理和推送:统一管理推送规则。
  • 鉴权:生产环境中鉴权非常重要。这里每个开发者需要根据自己的实际情况进行定制。

image.png

image.png

启动控制台

java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard.jar

工作流程

image.png

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

github.com/alibaba/spr…

日志

github.com/alibaba/Sen…

拦截详情日志:
${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 类似的问题。

参考