text: sentinel 冷启动原理 二、Sentinel 功能和设计理念 流量控制 流量控制在网络传输中是一个常用的概念，它用于调整网络包的发送数据。
  Sentinel 作为一个调配器，可以根据需要把随机的请求调整成合适的形状。
  流量控制设计理念 流量控制有以下几个角度:资源的调用关系 ，例如资源的调用链路，资源和资源之间的关系；
  运行指标 ，例如 QPS、线程池、系统负载等； 三、 熔断降级 什么是熔断降级 除了流量控制以外，及时对调用链路中的不稳定因素进行熔断也是 Sentinel 的使命之一。
  Sentinel 和 Hystrix 的原则是一致的: 当检测到调用链路中某个资源出现不稳定的表现，例如请求响应时间长或异常比例升高的时候，则对这个资源的调用进行限制，让请求快速失败，避免影响到其它的资源而导致级联故障。熔断降级设计理念 在限制的手段上，Sentinel 和 Hystrix 采取了完全不一样的方法。
  好处是资源和资源之间做到了最彻底的隔离。
  缺点是除了增加了线程切换的成本（过多的线程池导致线程数目过多），还需要预先给各个资源做线程池大小的分配，并且对于一些使用了 ThreadLocal 的场景来说会有问题（如 Spring 事务）。Sentinel 对这个问题采取了两种手段 通过并发线程数进行限制资源池隔离的方法不同， Sentinel 通过限制资源并发线程的数量，来减少不稳定资源对其它资源的影响。
  针对慢调用和异常对资源进行降级
  当依赖的资源出现响应时间过长后，所有对该资源的访问都会被直接拒绝，直到过了指定的时间窗口之后才重新渐进式地恢复。系统自适应保护 Sentinel 同时提供系统维度的自适应保护能力。四、Sentinel 是如何工作的 Sentinel 的主要工作机制如下：对主流框架提供适配或者显示的 API，来定义需要保护的资源，并提供设施对资源进行实时统计和调用链路分析。五、Sentinel基于并发线程数流控 采用基于线程数的限流模式后，我们不需要再显式地去进行线程池隔离。
  例如，当应用所依赖的下游应用由于某种原因导致服务不稳定、响应延迟增加，对于调用者来说，意味着吞吐量下降和更多的线程数占用，极端情况下甚至导致线程池耗尽。
  令牌桶算法图例如下： 预热模型
  Sentinel中的令牌桶算法，是参照Google Guava中的RateLimiter，在学习Sentinel中预热算法之前，先了解下整个预热模型，如下图： Guava中预热是通过控制令牌的生成时间，而Sentinel中实现不同：
  在Guava中，冷却因子coldFactor固定为3，上图中②是①的两倍
  Sentinel增加冷却因子coldFactor的作用，在Sentinel模型中，②是①的(coldFactor-1)倍，coldFactor默认为3，可以通过csp.sentinel.flow.cold.factor参数修改
  Sentinel中冷启动对应的FlowRule配置为RuleConstant.CONTROL_BEHAVIOR_WARM_UP,对应的Controller为WarmUpController，首先了解其中的属性和构造方法:
  count：FlowRule中设定的阈值
  warmUpPeriodSec：系统预热时间，代表上图中的②
  coldFactor：冷却因子，默认为3，表示倍数，即系统最"冷"时(令牌桶饱和时)，令牌生成时间间隔是正常情况下的多少倍
  warningToken：预警值，表示进入预热或预热完毕
  maxToken：最大可用token值，计算公式：warningToken+(2*时间*阈值)/(1+因子)，默认情况下为warningToken的2倍
  slope：斜度，(coldFactor-1)/count/(maxToken-warningToken)，用于计算token生成的时间间隔，进而计算当前token生成速度，最终比较token生成速度与消费速度，决定是否限流
  storedTokens：姑且可以理解为令牌桶中令牌的数量
  举例说明：FlowRule设定阈值count=5，即1s内QPS阈值为5，设置的预热时间默认为10s，即warmUpPeriodSec=10，冷却因子coldFactor默认为3，即count = 5，coldFactor=3，warmUpPeriodSec=10，则
  接下来学习，WarmUpController是如何进行限流的，进入canPass()方法:
  public boolean canPass ( Node node , int acquireCount , boolean prioritized ) { // 获取当前1s的QPS long passQps = ( long ) node . passQps ( ) ; // 获取上一窗口通过的qps long previousQps = ( long ) node . previousPassQps ( ) ; // 生成和滑落token syncToken ( previousQps ) ; // 如果进入了警戒线，开始调整他的qps long restToken = storedTokens . get ( ) ; // 如果令牌桶中的token数量大于警戒值，说明还未预热结束，需要判断token的生成速度和消费速度 if ( restToken >= warningToken ) { long aboveToken = restToken - warningToken ; // 消耗的速度要比warning快，但是要比慢 // y轴，当前token生成时间 current interval = restToken*slope+stableInterval // 计算此时1s内能够生成token的数量 double warningQps = Math . nextUp ( 1.0 / ( aboveToken * slope + 1.0 / count ) ) ; // 判断token消费速度是否小于生成速度，如果是则正常请求，否则限流 if ( passQps + acquireCount <= warningQps ) { return true ; } } else { // 预热结束，直接判断是否超过设置的阈值 if ( passQps + acquireCount <= count ) { return true ; } } return false ; }
  canPass()方法分为3个阶段：
  syncToken()：负责令牌的生产和滑落
  判断令牌桶中剩余令牌数
  若消耗速率大，则限流；否则请求正常通行
  仍然以count=5进行举例，警戒线warningToken=25，maxToken=50
  假设令牌桶中剩余令牌数storedTokens=30，即在预热范围内，此时restToken=30，slope=0.016，则aboveToken=30-25=5
  由斜率slope推导当前token生成时间间隔：(restToken-warningToken)*slope+stableInterval=5*0.016+1/5=0.28，即280ms生成一个token
  此时1s内生成token的数量=1/0.28≈4，即1s内生成4个token
  假设当前窗口通过的请求数量passQps=4，acquiredCount=1，此时passQps+acquiredCount=5>4，即令牌消耗速度大于生产速度，则限流
  如果剩余令牌数小于警戒值，说明系统已经处于高水位，请求稳定，则直接判断QPS与阈值，超过阈值则限流
  接下来分析Sentinel是如何生产及滑落token的，进入到syncToken()方法:
  获取当前时间秒数currentTime，与lastFilledTime进行比较，之所以取秒数，是因为时间窗口的设定为1s，若两个时间相等，说明还处于同一秒内，不进行token填充和滑落，避免重复问题
  令牌桶中添加token 当流量极大，令牌桶中剩余token远低于预警值时，添加token
  处于预热节点，单令牌的消耗速度小于系统最冷时令牌的生成速度，则添加令牌
  通过CAS操作，修改storedToken，并进行令牌扣减
  Sentinel采用令牌桶算法实现预热限流
  Sentinel限流是针对某时刻令牌的生成与消耗速度
  Sentinel通过比较整秒数，来判断是否需要进行令牌扣减，并通过CAS操作，保证同一时刻只能由1个线程成功操作，从而避免多次扣减passQps导致限流失效的问题
  -- 转载请声明来源和作者信息 --
  令牌桶算法的原理是：按一定的速率往令牌桶中放入令牌，当接收到请求时，从令牌桶申请令牌，只有拿到令牌的请求才能通过。
  例如，想要使用令牌桶算法限制接口的最大QPS为200，那么就要每5毫秒就要生产一个令牌放入令牌桶，且生产令牌放入的速度不变。
  冷启动算法用于控制令牌桶的令牌生产速率，即控制每个令牌生产的时间间隔。
  假设冷启动时长为10秒，初始状态为冷启动状态，限流阈值为200QPS，正常情况下生产令牌的速率应该为5毫秒/个，而在冷启动阶段，速率会从最小值上升至5毫秒/个，最小速率与冷启动系数有关，与冷启动周期时长有关。
  Sentinel与Guava的实现不同，Sentinel可能是出于对性能的考虑，并不控制每个请求的通过时间间隔，只控制每秒钟能通过的请求数。
  通过下面这张图来理解冷启动算法。
  坐标轴：
  横坐标storedPermits代表存储桶中的令牌数量；
  纵坐标代表获取一个令牌需要的时间，即请求通过的时间间隔；
  coldInterval：冷启动产生令牌的最大时间隔间，等于稳定产生令牌的时间间隔乘以冷启动系数（stableInterval * coldFactor），Sentinel中coldFactor默认为3。
  warmupPeriod：预热时间，即冷启动周期，对应上图中的梯形面积，Sentinel中默认为10秒。
  thresholdPermits：从冷启动到正常的令牌桶中令牌数量的阈值，当令牌桶中的令牌数量超过该值时，则进入冷启动阶段。
  根据长方形面积公式：长 * 宽 = 面积
  根据梯形的面积公式：（上低 + 下低）* 高 / 2
  Sentinel没有在每个请求通过时从令牌桶取走令牌，那么Sentinel是如何控制QPS的呢，我们再来看一张图：
  x1：当前令牌桶中超过thresholdPermits的令牌数量；
  y1：y1加上stableInterval等于当前令牌生产的时间间隔；
  根据斜率和x1可算出y1：
  当前秒生产令牌的时间间隔为：
  由于：stableInterval = 1.0(1秒) / 限流阈值(count)
  所以上述等式 = slope * (storedTokens - thresholdPermits) + 1.0 / count
  最后算得当前时间戳的QPS阈值为：
  Guava RateLimiter分析：
  Sentinel限流的核心功能QPS统计的实现原理Sentinel源码分析，了解Sentinel的整个工作流程
  Sentinel与OpenFeign整合实现熔断降级源码分析
  微信号：javaskill jvm分布式 编程语言 大数据 go
  并且，对于同一个资源或者不同资源可以分别创建多条限流规则，FlowSlot会对该资源的所有限流规则依次遍历，直到有规则触发限流或者所有规则遍历完毕。
  限流规则主要由下面几个因素组成：
  resource：资源名，即限流规则的作用对象
  grade : 限流阈值类型（QPS 或并发线程数）
  strategy : 限流策略（基于调用关系的流量控制）
  controlBehavior : 流量控制效果（直接拒绝、Warm Up、匀速排队）
  Sentinel中提供了两个限流纬度：
  默认情况下是根据QPS来限流的，这个属性是通过 grade 进行设置。
  二、并发线程数控制
  为了应对太多线程占用的情况，业内有使用隔离的方案，比如通过不同业务逻辑使用不同线程池来隔离业务自身之间的资源争抢（ Hystrix 线程池隔离 ）。
  这种隔离方案虽然隔离性比较好，但是代价就是线程数目太多，线程上下文切换的 (开销)比较大，特别是对低延时的调用有比较大的影响。
  Sentinel 并发控制不负责创建和管理线程池，而是简单统计当前请求上下文的线程数目（正在执行的调用数目），如果超出阈值，新的请求会被立即拒绝，效果类似于 Hystrix 信号量隔离 。
  并发线程数控制参数配置（ 并发线程数控制通常在调用端进行配置 ）：
  count: 此时它的含义是并发线程数量
  三、QPS流量控制
  Sentinel提供了四种流量控制行为
  直接拒绝（CONTROL_BEHAVIOR_DEFAULT）
  匀速排队（CONTROL_BEHAVIOR_RATE_LIMITER，漏桶算法 ）
  冷启动+匀速器（CONTROL_BEHAVIOR_WARM_UP_RATE_LIMITER），除了让流量缓慢增
  这四个行为，是通过 FlowRule 中的 controlBehavior 属性来控制，默认是直接拒绝。
  3.1、直接拒绝
  这种方式适用于对系统处理能力确切已知的情况下，比如通过压测确定了系统的准确水位时。
  当系统长期处于低水位的情况下，当流量突然增加时，直接把系统拉升到高水位可能瞬间把系统压
  3.3、匀速排队
  当请求数量远远大于阈值时，这些请求会排队等待，这个等待时间可以设置，如果超过等待时间，那这个请求会被拒绝。
  maxQueueingTimeMs：排队等待时间，表示每一次请求最长等待时间，默认是500ms
  四、基于调用关系的流量控制
  根据调用方限流（STRATEGY_DIRECT）
  根据调用链路入口限流（STRATEGY_CHAIN）
  具有关系的资源流量控制（STRATEGY_RELATE）
  4.1、根据调用方限流
  ${some_origin_name}，针对特定的调用者。
  other，表示针对除了${some_origin_name}以外的其他调用方的流量进行流量控制。