在前面两篇文章给大家介绍了 Sentinel 的功能和基本使用。现在我们继续来学习 Sentinel 控制台的基本使用,以及一些规则配置的说明。让大家能够在工作中使用 Sentinel 得心应手 (大部分理论和描述来源于官方文档和网络)。


在正文开始之前,我先说一下我的基本环境信息



  • ​jdk 1.8​
  • ​sentinel 1.8.0​
  • ​spring-boot 2.3.5.RELEASE​
  • ​spring-cloud Hoxton.SR8​
  • ​spring-cloud-alibaba 2.2.5.RELEASE​


控制台简介


Sentinel 提供一个轻量级的开源控制台,它提供机器发现以及健康情况管理、监控(单机和集群),规则管理和推送的功能。这里,我们将会详细讲述如何通过简单的步骤就可以使用这些功能。


Sentinel 控制台包含如下功能:



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


注意:Sentinel 控制台目前仅支持单机部署。Sentinel 控制台项目提供 Sentinel 功能全集示例,不作为开箱即用的生产环境控制台,若希望在生产环境使用需要自行定制和改造


Alibaba 提供了企业版本的 Sentinel 我们可以在 ​​aliyun.com​​​ 上面购买 ​​AHAS Sentinel​


查看机器列表以及健康情况


如果我们正确的接入 Sentinel 之后我们可以在 Sentinel 控制台的 ​​机器列表​​ 菜单中来查看我们服务节点的健康情况


Sentinel 流控规则详解_推送


如果 Sentinel 接入不成功,可以查阅 Sentinel 官方文档或者 FAQ 来对应排查


服务监控


1. 实时监控


同时,同一个服务下的所有机器的簇点信息会被汇总,并且秒级地展示在"实时监控"下。


注意: 实时监控仅存储 5 分钟以内的数据,如果需要持久化,需要通过调用实时监控接口来定制。


Sentinel 流控规则详解_链路_02


注意:请确保 Sentinel 控制台所在的机器时间与自己应用的机器时间保持一致,否则会导致拉不到实时的监控数据。


2. 簇点链路


簇点链路(单机调用链路)页面实时的去拉取指定客户端资源的运行情况。它一共提供两种展示模式:一种用树状结构展示资源的调用链路,另外一种则不区分调用链路展示资源的实时情况。


注意: 簇点链路监控是内存态的信息,它仅展示启动后调用过的资源。


Sentinel 流控规则详解_限流_03


注意:请确保 Sentinel 控制台所在的机器时间与自己应用的机器时间保持一致,否则会导致拉不到实时的监控数据。


3 流控规则


流量控制(flow control),其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。


​FlowSlot​​​ 会根据预设的规则,结合 ​​NodeSelectorSlot​​​、​​ClusterBuilderSlot​​​、​​StatisticSlot​​ 统计出来的实时信息进行流量控制。


Sentinel 流控规则详解_链路_04


限流的直接表现是在执行 ​​Entry nodeA = SphU.entry(resourceName)​​​ 的时候抛出 ​​FlowException​​​ 异常。​​FlowException​​​ 是 ​​BlockException​​​ 的子类,您可以捕捉 ​​BlockException​​ 来自定义被限流之后的处理逻辑。


Sentinel 在触发规则保护时,返回的异常页面是一样的。不好区分是因为哪种规则导致的异常。所以需要自定义异常返回信息,明确是触发了哪种类型的规则。


@Component
public class SentinelBlockHandler implements BlockExceptionHandler {
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
BlockException e) throws Exception {
CommonResult<Void> result = new CommonResult<>();
if (e instanceof FlowException) {
result = CommonResult.error(101, "接口限流了");
} else if (e instanceof DegradeException) {
result = CommonResult.error(102, "服务降级了");
} else if (e instanceof ParamFlowException) {
result = CommonResult.error(103, "热点参数限流了");
} else if (e instanceof SystemBlockException) {
result = CommonResult.error(104, "系统规则(负载/...不满足要求)");
} else if (e instanceof AuthorityException) {
result = CommonResult.error(105, "授权规则不通过");
}
// http状态码
httpServletResponse.setStatus(500);
httpServletResponse.setCharacterEncoding("utf-8");
httpServletResponse.setHeader("Content-Type", "application/json;charset=utf-8");
httpServletResponse.setContentType("application/json;charset=utf-8");
// spring mvc自带的json操作工具,叫jackson
new ObjectMapper().writeValue(httpServletResponse.getWriter(), result);
}
}


效果如下:


➜ curl http://127.0.0.1:8088/getStockDetail
{"code":1,"message":"this is a success message","data":{"id":1,"code":"STOCK==>1000"}}% ➜ curl http://127.0.0.1:8088/getStockDetail
{"code":1,"message":"this is a success message","data":{"id":1,"code":"STOCK==>1000"}}% ➜ curl http://127.0.0.1:8088/getStockDetail
{"code":101,"message":"接口限流了","data":null}%


阈值类型


线程数


并发数控制用于保护业务线程池不被慢调用耗尽。例如,当应用所依赖的下游应用由于某种原因导致服务不稳定、响应延迟增加,对于调用者来说,意味着吞吐量下降和更多的线程数占用,极端情况下甚至导致线程池耗尽。为应对太多线程占用的情况,业内有使用隔离的方案,比如通过不同业务逻辑使用不同线程池来隔离业务自身之间的资源争抢(线程池隔离)。这种隔离方案虽然隔离性比较好,但是代价就是线程数目太多,线程上下文切换的 overhead 比较大,特别是对低延时的调用有比较大的影响。Sentinel 并发控制不负责创建和管理线程池,而是简单统计当前请求上下文的线程数目(正在执行的调用数目),如果超出阈值,新的请求会被立即拒绝,效果类似于信号量隔离。并发数控制通常在调用端进行配置。


Sentinel 流控规则详解_限流_05


可以通过线程池模拟客户端调用, 也可以通过  Jmeter 模拟,触发流控的结果如下:


➜  ~ curl http://127.0.0.1:8088/getStockDetail
{"code":101,"message":"接口限流了","data":null}%


流控模式


调用关系包括调用方、被调用方;一个方法又可能会调用其它方法,形成一个调用链路的层次关系。


直接


当资源触发流控规则过后直接,抛出异常信息


➜  ~ curl http://127.0.0.1:8088/getStockDetail
{"code":101,"message":"接口限流了","data":null}%


关联


当两个资源之间具有资源争抢或者依赖关系的时候,这两个资源便具有了关联。比如对数据库同一个字段的读操作和写操作存在争抢,读的速度过高会影响写的速度,写的速度过高会影响读的速度。如果放任读写操作争抢资源,则争抢本身带来的开销会降低整体的吞吐量。可使用关联限流来避免具有关联关系的资源之间过度的争抢,举例来说,​​read_db​​​ 和 ​​write_db​​​ 这两个资源分别代表数据库读写,我们可以给 ​​read_db​​​ 设置限流规则来达到写优先的目的:设置 ​​strategy​​​ 为 ​​RuleConstant.STRATEGY_RELATE​​​ 同时设置 ​​refResource​​​ 为 ​​write_db​​。这样当写库操作过于频繁时,读数据的请求会被限流。


Sentinel 流控规则详解_推送_06


如果配置流控规则为关联模式,那么当 ​​/hello​​​ 接口超过阈值过后,就会对 ​​/getStockDetail​​ 接口触发流控规则。


链路


​NodeSelectorSlot​​​ 中记录了资源之间的调用链路,这些资源通过调用关系,相互之间构成一棵调用树。这棵树的根节点是一个名字为 ​​machine-root​​ 的虚拟节点,调用链的入口都是这个虚节点的子节点。


一棵典型的调用树如下图所示:


                  machine-root
/ \
/ \
Entrance1 Entrance2
/ \
/ \
DefaultNode(nodeA) DefaultNode(nodeA)


上图中来自入口 ​​Entrance1​​​ 和 ​​Entrance2​​​ 的请求都调用到了资源 ​​NodeA​​​,Sentinel 允许只根据某个入口的统计信息对资源限流。比如我们可以设置 ​​strategy​​​ 为 ​​RuleConstant.STRATEGY_CHAIN​​​,同时设置 ​​refResource​​​ 为 ​​Entrance1​​​ 来表示只有从入口 ​​Entrance1​​​ 的调用才会记录到 ​​NodeA​​​ 的限流统计当中,而不关心经 ​​Entrance2​​ 到来的调用。


调用链的入口(上下文)是通过 API 方法 ​​ContextUtil.enter(contextName)​​ 定义的,其中 contextName 即对应调用链路入口名称。详情可以参考 ContextUtil 文档。]


Sentinel 流控规则详解_推送_07


测试会发现 ​​链路​​ 不会生效


从1.6.3版本开始,Sentinel Web filter默认收敛所有URL的入口context,因此链路限流不生效。1.7.0版本开始(对应SCA 2.1.1.RELEASE),我们在CommonFilter引入了WEB_CONTEXT_UNIFY这个init parameter,用于控制是否收敛context。将其配置为false即可根据不同的URL进行链路限流。参考:https://github.com/alibaba/sentinel/issues/1213


解决方案:


1.7.0 版本开始(对应Spring Cloud Alibaba的2.1.1.RELEASE) 需要新增依赖


@Configuration
public class FilterContextConfig {
@Bean
public FilterRegistrationBean sentinelFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new CommonFilter());
registration.addUrlPatterns("/*");

// 入口资源关闭聚合
registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false");
registration.setName("sentinelFilter");
registration.setOrder(1);
return registration;
}
}


然后我们再尝试触发流控规则, 对 ​​/getStockDetail​​​ 进行访问,这里返回了​​FlowException​


Sentinel 流控规则详解_推送_08


默认情况会返回


Sentinel 流控规则详解_推送_09


如果我们使用 OpenFeign 不添加 ​​fallbackFactory​​ 就会返回500 , 如果我们添加了就可以避免这个问题。


// Controller
@Autowired
private StockFeign stockFeign;
@GetMapping("/getStockDetail")
public CommonResult<StockModel> getStockDetail() {
CommonResult<StockModel> result = stockFeign.getStockDetail();
if (result.getCode() != 1) {
return CommonResult.error(null, result.getCode(), result.getMessage());
}
return result;
}
// FeignClient
@FeignClient(name = "stock-service")
//, fallbackFactory = StockFeignFallbackFactory.class)
public interface StockFeign {
@GetMapping("/getStockDetail")
CommonResult<StockModel> getStockDetail();
}


Sentinel 部分源码:


Sentinel 流控规则详解_推送_10


所以,我们在设置链路流控规则的时候一定要设置 fallbackFactory。不然无法处理 ​​FlowExecption​​ 异常信息,造成系统出错。对于个人而言,Sentinel 的链路规则比不是特别的好用,无特殊要求,不建议使用,或者选择Sentinel 的收费版本 AHAS


流控效果


当 QPS、线程数超过某个阈值的时候,则采取措施进行流量控制。流量控制的效果包括以下几种:直接拒绝Warm Up匀速排队


直接拒绝


直接拒绝(​​RuleConstant.CONTROL_BEHAVIOR_DEFAULT​​)方式是默认的流量控制方式,当QPS超过任意规则的阈值后,新的请求就会被立即拒绝,拒绝方式为抛出FlowException 这种方式适用于对系统处理能力确切已知的情况下,比如通过压测确定了系统的准确水位时。


Warm up


Warm Up(​​RuleConstant.CONTROL_BEHAVIOR_WARM_UP​​)方式,即预热/冷启动方式。当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。


通常冷启动的过程系统允许通过的 QPS 曲线如下图所示:


Sentinel 流控规则详解_限流_11


默认 coldFactor 为 3,即请求 QPS 从 threshold / 3 开始,经预热时长逐渐升至设定的 QPS 阈值。


规则设置如下图所示:


Sentinel 流控规则详解_链路_12


通过 Jmeter 请求过后,可以看到如下效果,完成流控


Sentinel 流控规则详解_推送_13


匀速排队


匀速排队(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER)方式会严格控制请求通过的间隔时间,也即是让请求以均匀的速度通过,对应的是漏桶算法。




这种方式主要用于处理间隔性突发的流量,例如消息队列。想象一下这样的场景,在某一秒有大量的请求到来,而接下来的几秒则处于空闲状态,我们希望系统能够在接下来的空闲期间逐渐处理这些请求,而不是在第一秒直接拒绝多余的请求。


注意:匀速排队模式暂时不支持 QPS > 1000 的场景。


规则设置如下图所示:


Sentinel 流控规则详解_限流_14


然后我们通过 jmeter 请求过后可以看到如下效果:


Sentinel 流控规则详解_链路_15


4. 降级规则


流量控制以外,对调用链路中不稳定的资源进行熔断降级也是保障高可用的重要措施之一。一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。例如,支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。


熔断降级策略


Sentinel 提供以下几种熔断策略:


  • 慢调用比例 (​​SLOW_REQUEST_RATIO​​):选择以慢调用比例作为阈值,需要设置允许的慢调用 RT(即最大的响应时间),请求的响应时间大于该值则统计为慢调用。当单位统计时长(​​statIntervalMs​​)内请求数目大于设置的最小请求数目,并且慢调用的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求响应时间小于设置的慢调用 RT 则结束熔断,若大于设置的慢调用 RT 则会再次被熔断。

我们可以在控制台配置:

Sentinel 流控规则详解_限流_16

jmeter 模拟请求

Sentinel 流控规则详解_推送_17


  • 异常比例 (​​ERROR_RATIO​​):当单位统计时长(​​statIntervalMs​​)内请求数目大于设置的最小请求数目,并且异常的比例大于阈值,则接下来的熔断时长内请求会自动被熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。异常比率的阈值范围是 ​​[0.0, 1.0]​​,代表 0% - 100%。


我们可以在控制台配置:


Sentinel 流控规则详解_链路_18


  • 异常数 (​​ERROR_COUNT​​):当单位统计时长内的异常数目超过阈值之后会自动进行熔断。经过熔断时长后熔断器会进入探测恢复状态(HALF-OPEN 状态),若接下来的一个请求成功完成(没有错误)则结束熔断,否则会再次被熔断。


我们可以在控制台配置:


Sentinel 流控规则详解_推送_19


熔断降级说明


熔断降级规则(DegradeRule)包含下面几个重要的属性:

Field

说明

默认值

resource

资源名,即规则的作用对象


grade

熔断策略,支持慢调用比例/异常比例/异常数策略

慢调用比例

count

慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值


timeWindow

熔断时长,单位为 s


minRequestAmount

熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入)

5

statIntervalMs

统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入)

1000 ms

slowRatioThreshold

慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)



5. 热点规则


何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的 Top K 数据,并对其访问进行限制。比如:



  • 商品 ID 为参数,统计一段时间内最常购买的商品 ID 并进行限制
  • 用户 ID 为参数,针对一段时间内频繁访问的用户 ID 进行限制


热点参数限流会统计传入参数中的热点参数,并根据配置的限流阈值与模式,对包含热点参数的资源调用进行限流。热点参数限流可以看做是一种特殊的流量控制,仅对包含热点参数的资源调用生效。


Sentinel 流控规则详解_链路_20


Sentinel 利用 LRU 策略统计最近最常访问的热点参数,结合令牌桶算法来进行参数级别的流控。热点参数限流支持集群模式。


热点规则配置需要注意:


1. 首先资源必须是通过 ​​@SentinelResource​​ 申明


2. 参数类型必须是基础数据类型, 否则配置无效


热点规则配置如下图所示:


Sentinel 流控规则详解_推送_21


注意:资源名称要和 @SentinelResource  中的资源名称对应才能生效


控制器类的代码如下所示:


@SentinelResource(value = "ResOrderGet",
fallback = "fallback",
fallbackClass = SentinelExceptionHandler.class,
blockHandler = "blockHandler",
blockHandlerClass = SentinelExceptionHandler.class
)
@GetMapping("/order/get/{id}")
public CommonResult<StockModel> getStockDetails(@PathVariable Integer id) {
StockModel stockModel = new StockModel();
stockModel.setCode("STOCK==>1000");
stockModel.setId(id);
return CommonResult.success(stockModel);
}
// 异常处理类
public class SentinelResourceExceptionHandler {
//限流熔断业务逻辑
public static CommonResult<StockModel> blockHandler(@PathVariable Integer id) {
return CommonResult.error(null, -100, "系统错误 (限流熔断业务逻辑)");
}
//异常降级业务逻辑
public static CommonResult<StockModel> fallback(@PathVariable Integer id) {
return CommonResult.error(null, -100, "系统错误 (异常降级业务逻辑)");
}
}


返回异常信息:


Sentinel 流控规则详解_推送_22


6 授权规则


很多时候,我们需要根据调用来源来判断该次请求是否允许放行,这时候可以使用 Sentinel 的来源访问控制(黑白名单控制)的功能。来源访问控制根据资源的请求来源(​​origin​​)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。


调用方信息通过 ​​ContextUtil.enter(resourceName, origin)​​​ 方法中的 ​​origin​​ 参数传入。


Sentinel提供了 RequestOriginParser 接口来处理访问来源,Sentinel保护的资源如果被访问,就会调用 RequestOriginParser解析访问来源。


// 注意导包
import com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser;
import javax.servlet.http.HttpServletRequest;
public class SentinelRequestOriginParser implements RequestOriginParser {
@Override
public String parseOrigin(HttpServletRequest request) {
return request.getParameter("origin");
}
}


修改 Config 配置信息


@Configuration
public class FilterContextConfig {
@Bean
public FilterRegistrationBean sentinelFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new CommonFilter());
registration.addUrlPatterns("/*");
// 入口资源关闭聚合
registration.addInitParameter(CommonFilter.WEB_CONTEXT_UNIFY, "false");
registration.setName("sentinelFilter");
registration.setOrder(1);
// CommonFilter 的 BlockException 自定义处理逻辑
WebCallbackManager.setUrlBlockHandler(new SentinelFlowHandler());
//解决授权规则不生效的问题
//com.alibaba.csp.sentinel.adapter.servlet.callback.RequestOriginParser
WebCallbackManager.setRequestOriginParser(new SentinelRequestOriginParser());
return registration;
}
}


规则配置


Sentinel 流控规则详解_链路_23


执行请求

正常通过


Sentinel 流控规则详解_推送_24


异常不通过

Sentinel 流控规则详解_限流_25



7 系统规则


系统保护规则是从应用级别的入口流量进行控制,从单台机器的 load、CPU 使用率、平均 RT、入口 QPS 和并发线程数等几个维度监控应用指标,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。


系统保护规则是应用整体维度的,而不是资源维度的,并且仅对入口流量生效。入口流量指的是进入应用的流量(​​EntryType.IN​​),比如 Web 服务或 Dubbo 服务端接收的请求,都属于入口流量。


系统规则支持以下的模式:



  • Load 自适应(仅对 Linux/Unix-like 机器生效):系统的 load1 作为启发指标,进行自适应系统保护。当系统 load1 超过设定的启发值,且系统当前的并发线程数超过估算的系统容量时才会触发系统保护(BBR 阶段)。系统容量由系统的 ​​maxQps * minRt​​ 估算得出。设定参考值一般是 ​​CPU cores * 2.5​​。
  • CPU usage(1.5.0+ 版本):当系统 CPU 使用率超过阈值即触发系统保护(取值范围 0.0-1.0),比较灵敏。
  • 平均 RT:当单台机器上所有入口流量的平均 RT 达到阈值即触发系统保护,单位是毫秒。
  • 并发线程数:当单台机器上所有入口流量的并发线程数达到阈值即触发系统保护。
  • 入口 QPS:当单台机器上所有入口流量的 QPS 达到阈值即触发系统保护。


原理


如下图所示


Sentinel 流控规则详解_推送_26


我们把系统处理请求的过程想象为一个水管,到来的请求是往这个水管灌水,当系统处理顺畅的时候,请求不需要排队,直接从水管中穿过,这个请求的RT是最短的;反之,当请求堆积的时候,那么处理请求的时间则会变为:排队时间 + 最短处理时间。


  • 推论一: 如果我们能够保证水管里的水量,能够让水顺畅的流动,则不会增加排队的请求;也就是说,这个时候的系统负载不会进一步恶化。


我们用 T 来表示(水管内部的水量),用RT来表示请求的处理时间,用P来表示进来的请求数,那么一个请求从进入水管道到从水管出来,这个水管会存在 ​​P * RT​​​ 个请求。换一句话来说,当 ​​T ≈ QPS * Avg(RT)​​ 的时候,我们可以认为系统的处理能力和允许进入的请求个数达到了平衡,系统的负载不会进一步恶化。


接下来的问题是,水管的水位是可以达到了一个平衡点,但是这个平衡点只能保证水管的水位不再继续增高,但是还面临一个问题,就是在达到平衡点之前,这个水管里已经堆积了多少水。如果之前水管的水已经在一个量级了,那么这个时候系统允许通过的水量可能只能缓慢通过,RT会大,之前堆积在水管里的水会滞留;反之,如果之前的水管水位偏低,那么又会浪费了系统的处理能力。


  • 推论二: 当保持入口的流量是水管出来的流量的最大的值的时候,可以最大利用水管的处理能力。


然而,和 TCP BBR 的不一样的地方在于,还需要用一个系统负载的值(load1)来激发这套机制启动。


注:这种系统自适应算法对于低 load 的请求,它的效果是一个“兜底”的角色。对于不是应用本身造成的 load 高的情况(如其它进程导致的不稳定的情况),效果不明显。


配置页面


Sentinel 流控规则详解_链路_27


触发流控规则

Sentinel 流控规则详解_链路_28


8 集群流控


为什么要使用集群流控呢?假设我们希望给某个用户限制调用某个 API 的总 QPS 为 50,但机器数可能很多(比如有 100 台)。这时候我们很自然地就想到,找一个 server 来专门来统计总的调用量,其它的实例都与这台 server 通信来判断是否可以调用。这就是最基础的集群流控的方式。


另外集群流控还可以解决流量不均匀导致总体限流效果不佳的问题。假设集群中有 10 台机器,我们给每台机器设置单机限流阈值为 10 QPS,理想情况下整个集群的限流阈值就为 100 QPS。不过实际情况下流量到每台机器可能会不均匀,会导致总量没有到的情况下某些机器就开始限流。因此仅靠单机维度去限制的话会无法精确地限制总体流量。而集群流控可以精确地控制整个集群的调用总量,结合单机限流兜底,可以更好地发挥流量控制的效果。


集群流控中共有两种身份:



  • Token Client:集群流控客户端,用于向所属 Token Server 通信请求 token。集群限流服务端会返回给客户端结果,决定是否限流。
  • Token Server:即集群流控服务端,处理来自 Token Client 的请求,根据配置的集群规则判断是否应该发放 token(是否允许通过)。


规则推送


Sentinel 控制台同时提供简单的规则管理以及推送的功能。规则推送分为 3 种模式,包括 "原始模式"、"Pull 模式" 和"Push 模式"。


这里先简单的介绍"原始模式"。


规则管理


您可以在控制台通过接入端暴露的 HTTP API 来查询规则。



Sentinel 流控规则详解_推送_29

规则推送


Sentinel 流控规则详解_链路_30


目前控制台的规则推送也是通过 规则查询更改 HTTP API 来更改规则。这也意味着这些规则仅在内存态生效,应用重启之后,该规则会丢失。


注:若通过控制台推送规则时出现 invalid type 或 empty type 的错误,请确保 transport 模块版本与 core 模块版本保持一致;若控制台版本 >= 1.7.1,请将接入端的相关依赖也升级至 1.7.1 及以上版本。


以上是原始模式。当了解了原始模式之后,我们非常鼓励您通过 动态规则 并结合各种外部存储来定制自己的规则源。我们推荐通过动态配置源的控制台来进行规则写入和推送,而不是通过 Sentinel 客户端直接写入到动态配置源中。在生产环境中,我们推荐 push 模式,具体可以参考:在生产环境使用 Sentinel。


注:若要使用集群流控功能,则必须对接动态规则源,否则无法正常使用。您也可以接入 AHAS Sentinel 快速接入全自动托管、高可用的集群流控能力。


Sentinel 同时还提供应用维度规则推送的示例页面(流控规则页面,前端路由为 ​​/v2/flow​​),用户改造控制台对接配置中心后可直接通过 v2 页面推送规则至配置中心。Sentinel 抽取了通用接口用于向远程配置中心推送规则以及拉取规则:



  • ​DynamicRuleProvider<T>​​: 拉取规则(应用维度)
  • ​DynamicRulePublisher<T>​​: 推送规则(应用维度)


用户只需实现 ​​DynamicRuleProvider​​​ 和 ​​DynamicRulePublisher​​​ 接口,并在 v2 的 controller 中通过 ​​@Qualifier​​ 注解替换相应的 bean 即可实现应用维度推送。我们提供了 Nacos 和 Apollo 的示例,改造详情可参考 应用维度规则推送示例。


鉴权


从 Sentinel 1.5.0 开始,控制台提供通用的鉴权接口 AuthService,用户可根据需求自行实现。


从 Sentinel 1.6.0 起,Sentinel 控制台引入基本的登录功能,默认用户名和密码都是 ​​sentinel​​。该鉴权能力非常基础,生产环境使用建议根据安全需要自行改造。


Sentinel 流控规则详解_推送_31


用户可以通过如下参数进行配置:



  • ​-Dsentinel.dashboard.auth.username=sentinel​​ 用于指定控制台的登录用户名为 ​​sentinel​​;
  • ​-Dsentinel.dashboard.auth.password=123456​​ 用于指定控制台的登录密码为 ​​123456​​;如果省略这两个参数,默认用户和密码均为 ​​sentinel​​;
  • ​-Dserver.servlet.session.timeout=7200​​ 用于指定 Spring Boot 服务端 session 的过期时间,如 ​​7200​​ 表示 7200 秒;​​60m​​ 表示 60 分钟,默认为 30 分钟;


同样也可以直接在 Spring properties 文件中进行配置。


注意:部署多台控制台时,session 默认不会在各实例之间共享,这一块需要自行改造。


参考文档


​https://github.com/alibaba/Sentinel/wiki/控制台​