zoukankan      html  css  js  c++  java
  • Sentinel

      计数器算法:
        指定周期内限制最大值,到达下个周期时从0开始计数。
        缺陷:临界值问题00:01:59和00:02:01分别出现最大值的流量,导致这2s内总流量达到最大值流量的2倍
    
      滑动窗口算法(Sentinel采用此算法):
        滑动窗口的大小为若干个小时间窗的和,每个小时间窗可限x个请求,
        滑动窗口随着时间移动,滑动时间窗口的流量等于其包含的完整小时间窗中的流量和
    
      令牌桶限流算法:
        系统以恒定的速率生产令牌放到令牌桶中,若桶已满则不放,可应对突发流量
        每个请求处理前都需要从令牌桶中获取令牌,若获取不到则触发限流策略
    
      漏桶限流算法:
        系统维护一个固定大小的容器,同时以固定速率漏水
        每次请求时先看当前桶中的水满没满(当前水量=上次更新后的水量-时间跨度*漏水速率),满了就限流,没满就正常处理
        https://baijiahao.baidu.com/s?id=1666902623332115966&wfr=spider&for=pc
    限流算法
    Sentinel三种熔断策略:
    
      1. 平均响应时长:1s内累计有5个请求的平均响应时长超过阈值,触发熔断,在接下来的熔断时间窗内的请求直接降级
      2. 异常比例:1s内请求数>=5,且1s内异常请求数占总请求数的比例超过阈值,触发熔断,在接下来的熔断时间窗内的请求直接降级
      3. 异常数:1min内异常请求数超过阈值,触发熔断,在接下来的熔断时间窗内的请求直接降级
    Sentinel三种熔断策略

    流控的两种类型:QPS和线程数,QPS是资源每秒查询数,线程数是资源占用的线程上限,防止线程耗尽服务雪崩 P180

    Sentinel Dashboard中配置的流控规则是存储于内存中的,Dashboard服务重启后规则全部丢失,需要集成动态数据源提供规则持久化功能

    Sentinel集成Nacos作为数据源,实现动态流控:P190

      1. 在服务的application.yml文件中配置服务名、dashboard服务地址、数据源地址及指定配置的data-id、group-id、data-type、rule-type(流控、降级、热点、授权 P188)

      2. 登录Nacos Console,根据1中指定的配置参数创建配置,在配置内容中配置7项规则条件,即完成Sentinel规则的创建

    {
        "resource": "/dynamic",        #资源名
        "limitApp": "default",        #针对来源
        "grade": 1,                    #阈值类型 1-QPS 0-线程数
        "count": 1,                    #单机阈值
        "strategy": 0,
        "controlBehavior": 0,
        "clusterMode": false         #是否集群
    }
    规则内容-7项

      3. 登录Sentinel Dashboard,2中创建的规则已自动加载

    Sentinel集成Nacos作为数据源,在Nacos中修改流控规则后,Dashboard从Nacos中读取到的规则就是最新的
    Sentinel Dashboard中修改流控规则后,Dashboard不支持自动同步到Nacos做持久化更新
    Nacos作为配置中心,并没有Dashboard提供修改规则专用的UI界面,如果使用Nacos修改规则容易出错
    Sentinel集成Nacos作为数据源存在哪些问题?

    Dashboard进行规则的CRUD时,后台都是通过FlowControllerV1这个类进行处理

      还有一个FlowControllerV2类,有两个功能:

        1. DynamicRuleProvider:负责从数据源中拉取配置规则,在Dashboard中展示

        2. DynamicRulePublisher:负责将Dashboard中修改的规则推送给数据源,最持久化更新存储

    修改Sentinel Dashboard源码,支持Dashboard-Nacos同步,步骤:

      1. 下载Sentinel Dashboard源码

      2. 创建FlowControllerV2中DynamicRuleProvider接口的实现类,重写getRules方法从Nacos中获取配置规则

      3. 创建FlowControllerV2中DynamicRulePublisher接口的实现类,重写publish方法,建立与Nacos的HTTP连接,将规则Post给它

      4. 在FlowControllerV2类注入DynamicRuleProvider和DynamicRulePublisher接口的上面,用@Qualifier指定2、3中的实现类名(首字母小写)

      5. 修改Dashboard的pom.xml中配置、一个html中将V1去掉

      6. 打jar包启动Dashboard

    Sentinel处理链

      Slot链,责任链模式,比如LogSlot (日志处理槽) -> StatisticSlot (统计槽) -> ParamFlowSlot (根据统计槽的数据进行热点参数规则校验) ->

      FlowSlot (根据统计槽的数据进行流控规则校验) -> DegradeSlot (根据统计槽的数据进行降级规则校验)等

    实时指标统计流程(StatisticSlot-StatisticNode实现统计)

      底层根据LongAdder.add()这种CAS操作进行累计请求通过数、线程数

      滑动计数器ArrayMetric,当进行累计时,先获取当前时间窗口,再做累计

      ArrayMetric中通过LeapArray来存储数据,是环形数据结构,只存储最近固定个数的时间窗口,过期的窗口内存会被覆盖

      LeapArray中获取当前时间窗对象的流程:

        先根据当前时间换算得到当前时间窗的下标,然后获取对应时间窗统计对象WindowWrap,这时有三种情况:

        1. 时间窗不存在,新建时间窗,并用CAS操作(只一次,不循环)添加到存储所有窗口的AtomicReferenceArray<WindowWrap<T>>原子数组的对应下标位置中

         1.1 若CAS成功,返回新建的时间窗

         1.2 若CAS失败,说明有其他线程在同时向原子数组的对应下标位置放新窗口,

            调用Thread.yeild()释放CPU占用,接着会进while继续判断,这时候一般就进入2.1的情况了

        2. 时间窗存在,然后判断这个时间窗的开始时间 与 当前时间换算得到的时间窗开始时间 是否相同

         2.1 若相同直接返回此时间窗

         2.2 若不相同证明时间窗已过期,使用ReentrantLock.tryLock()只尝试加一下锁,

            若拿到锁就重置窗口,若没拿到调用Thread.yeild()释放CPU占用,接着会进while继续判断,这时候一般就进入2.1的情况了

    热点限流(ParamFlowSlot)

      场景:防止网络爬虫和恶意攻击,限制客户端IP,客户端IP地址就是一种热点参数;

         高并发修改数据库同一行,mysql需要加行锁,这行数据也是一种热点参数

      原理:滑动窗口算法+LRU策略(最近最少使用)实现热点参数的统计,LRU策略统计单位时间内最常访问的热点数据,滑动窗口统计每个参数的QPS

    流量控制(FlowSlot)

      一个接口可以配置多个限流规则,有三种情况 P215:

        1. 不区分流量来源,对所有调用此接口的应用做整体限流

        2. 可针对同一个接口配置多个限流规则,每个规则配置不同的来源,可保证某些关键流量来源服务的并发量

        3. 配一个总体限流规则,在针对某个来源配置一个单独的限流规则,配合使用

    服务降级(DegradeSlot)

      1. 请求达到DegradeSlot槽进行处理

      2. 先根据请求资源获取资源所有已配置的降级规则Set集合

      3. 对Set遍历,逐个进行降级校验,根据规则降级类型(平均响应时间、失败率、失败数),从StatisticNode中获取需要的统计数据进行计算并判断

  • 相关阅读:
    学习笔记5_Day09_网站访问量统计小练习
    学习笔记4_ServletContext(重要整个Web应用的动态资源之间共享数据)
    学习笔记03_Day09-----Servle与反射()
    学习笔记2_Day09_servlet的细节
    学习笔记1_Day09_Servlet
    OC对数组排序的方法
    sqlite事务处理
    封装数据库
    JsonModel的使用
    RBAC表
  • 原文地址:https://www.cnblogs.com/yfzhou528/p/13707080.html
Copyright © 2011-2022 走看看