分布式组件-Sentinel-常见流量控制算法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分布式组件-Sentinel-常见流量控制算法相关的知识,希望对你有一定的参考价值。

参考技术A 在指定周期内累加访问次数,当访问次数达到设定的阈值时,触发限流策略,当进入下一个时间周期时进行访问次数的清零。

限定每一分钟能够处理的总的请求数为100,在第一个一分钟内,一共请求了60次。接着到第二个一分钟,counter又从0开始计数,在一分半钟时,已经达到了最大限流的阈值,这个时候后续的所有请求都会被拒绝。这种算法可以用在短信发送的频次限制上,比如限制同一个用户一分钟之内触发短信发送的次数。

这种算法存在一个临界问题,这种算法针对的是固定周期的累加访问次数,但是如果服务器需要做到的是限制每个一分钟内的访问量,这种算法显然就不适用了,因为计数器算法无法限制每隔一段时间内的访问量均不超过阈值。

在第一分钟的0:58和第二分钟的1:02这个时间段内,分别出现了100个请求,整体来看就会出现4秒内总的请求量达到200,超出了设置的阈值。

滑动窗口算法是将时间周期分为N个小周期(窗口),分别记录每个小周期内访问次数,然后根据时间将窗口往前滑动并删除过期的小时间窗口。最终只需要统计滑动窗口范围内的所有小时间窗口总的计数即可。

将一分钟拆分为4个小时间窗口,每个小时间窗口最多能够处理25个请求。并且通过虚线框表示滑动窗口的大小(当前窗口的大小是2,也就是在这个窗口内最多能够处理50个请求)。同时滑动窗口会随着时间往前移动,比如前面15s结束之后,窗口会滑动到15s~45s这个范围,然后在新的窗口中重新统计数据。

由此可见,当滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑,限流的统计就会越精确。此算法可以很好的解决固定窗口算法的临界问题。

令牌桶是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。对于每一个请求,都需要从令牌桶中获得一个令牌,如果没有获得令牌,则需要触发限流策略。

系统会以一个恒定速度(r tokens/sec)往固定容量的令牌桶中放入令牌,如果此时有客户端请求过来,则需要先从令牌桶中拿到令牌以获得访问资格。

假设令牌生成速度是每秒10个,也就等同于QPS=10,此时在请求获取令牌的时候,会存在三种情况:

• 请求速度大于令牌生成速度:那么令牌会很快被取完,后续再进来的请求会被限流。

• 请求速度等于令牌生成速度:此时流量处于平稳状态。

• 请求速度小于令牌生成速度:说明此时系统的并发数并不高,请求能被正常处理。

由于令牌桶有固定的大小,当请求速度小于令牌生成速度时,令牌桶会被填满。所以令牌桶能够处理突发流量,也就是在短时间内新增的流量系统能够正常处理,这是令牌桶的特性。

漏桶限流算法的主要作用是控制数据注入网络的速度,平滑网络上的突发流量。

在漏桶算法内部同样维护一个容器,这个容器会以恒定速度出水,不管上面的水流速度多快,漏桶水滴的流出速度始终保持不变。访问请求到达时直接放入漏桶,如当前容量已达到上限(限流值),则进行丢弃(触发限流策略)。漏桶以固定的速率进行释放访问请求(即请求通过),直到漏桶为空。实际上消息中间件就使用了漏桶限流的思想,不管生产者的请求量有多大,消息的处理能力取决于消费者。

在漏桶限流算法中,存在以下几种可能的情况:

• 请求速度大于漏桶流出水滴的速度:也就是请求数超出当前服务所能处理的极限,将会触发限流策略。

• 请求速度小于或者等于漏桶流出水滴的速度,也就是服务端的处理能力正好满足客户端的请求量,将正常执行。

漏桶限流算法和令牌桶限流算法的实现原理相差不大,最大的区别是漏桶无法处理短时间内的突发流量,漏桶限流算法是一种恒定速度的限流算法。

SpringCloud系列——流量控制组件Sentinel实战

前言

在微服务应用中,保证服务和服务之间的稳定性是至关重要的。目前在springcloud技术栈中,最常见的俩种服务保护组件就是Netflix公司的hytrix和阿里巴巴出品的Sentinel。本节我们主要介绍一下Sentinel这款功能强大的精品组件。Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流、流量整形、熔断降级、系统负载保护、热点防护等多个维度来帮助开发者保障微服务的稳定性。看到这一段官方描述我们大概就对Sentinel组件能够干什么,有了一个初步的认识,具体的官方文档说明,请参考官方地址:https://github.com/alibaba/Sentinel/wiki/%E4%B8%BB%E9%A1%B5,话不多说,开始我们的sentinel开发实战。

正文

  • 安装sentinel客户端

①下载sentinel客户端

地址:https://github.com/alibaba/Sentinel/releases

②安装sentinel客户端命令:java -Dserver.port=8081 -Dcsp.sentinel.dashboard.server=localhost:8081 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.8.1.jar -Dcsp.sentinel.app.type=1

③登录sentinel客户端,默认用户名和密码都是sentinel

  • 微服务集成sentinel

说明:使用nacos作为sentinel相关规则配置数据的持久化存储中心,在网关层实现服务的限流、降级等操作,分别通过router和API俩种方式实现微服务限流的实战案例。

①引入 sentinel的pom依赖

<!--sentinel配置数据源nacos-->
<dependency>
	<groupId>com.alibaba.csp</groupId>
	<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>

② 引入gateway网关整合sentinel的相关pom依赖

<!-- https://mvnrepository.com/artifact/com.alibaba.cloud/spring-cloud-alibaba-sentinel-gateway -->
<dependency>
	<groupId>com.alibaba.cloud</groupId>
	<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
	<version>2.2.5.RELEASE</version>
</dependency>


<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-gateway -->
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-gateway</artifactId>
	<version>2.2.5.RELEASE</version>
</dependency>

③配置网关的相关sentinel配置

spring:
  cloud:
    gateway:
      routes:
        - id: xxx_manager_router #路由ID
          uri: lb://xxx-manager #负载均衡到转发的微服务地址
          predicates:
            - Path=/api/manager/** #路由断言,以/api/manager/开头的访问请求使用该路由策略转发,转发到上面配置的微服务
          filters:
            - RewritePath=/api/manager/(?<segment>.*),/$\\{segment} #路径改写,将网关的请求地址改写为真实的微服务地址

    #sentinel配置
    sentinel:
      transport:
        dashboard: localhost:8081
        port: 8719
      filter:
        enabled: true
      scg: #配置限流之后,响应内容
        fallback:
          mode: response
          response-status: 200
          response-body: "服务繁忙,请稍后重试!"
          content-type: "application/json"
      #数据源配置
      datasource:
        gw-router-group:
          nacos:
            server-addr: ${spring.cloud.nacos.server-addr}
            dataId: ${spring.application.name}-gw-router-group-flow-rules
            groupid: DEFAULT_GROUP
            data-type: json
            rule-type: gw-flow
        gw-api-group:
          nacos:
            server-addr: ${spring.cloud.nacos.server-addr}
            dataId: ${spring.application.name}-gw-api-group-flow-rules
            groupid: DEFAULT_GROUP
            data-type: json
            rule-type: gw-api-group

④在nacos配置限流策略

(1)xxx-gw-router-group-flow-rules配置

[
  {
    "resource": "xxx_manager_router",
    "limitApp": "default",
    "grade": 1,
    "count":12,
    "strategy": 0,
    "controlBehavior": 0,
    "clusterMode": false
  },
  {
    "resource": "xxx_manager_api",
    "count": 2,
    "grade": 1,
    "resourceMode": 1
  }
]

(2)xxx-gw-api-group-flow-rules配置

[
  {
    "apiName": "xxx_manager_api",
    "predicateItems": [
      {
        "pattern": "/api/manager/sysCode/*",
        "matchStrategy": 1
      }
    ]
  }
]

说明:具体的配置参数说明请参考官网地址https://github.com/alibaba/Sentinel/wiki/%E7%BD%91%E5%85%B3%E9%99%90%E6%B5%81

⑤测试验证

说明:通过网关访问以/api/manager/sysCode/*的请求,可以看到,频繁调用,会出现配置限流的提示,这里的API限流配置的是每秒钟2次就会限流,router限流配置是每秒钟12次就会限流,可以通过修改nacos配置中心的count参数动态修改限流的策略

⑥sentinel控制台可以查看流控配置以及具体的访问请求流量等信息

结语

ok,到这里关于Sentinel的应用实战就结束了,我们下期见。。。

以上是关于分布式组件-Sentinel-常见流量控制算法的主要内容,如果未能解决你的问题,请参考以下文章

Sentinel分布式服务架构高可用流量防护组件之微服务保护

Sentinel分布式服务架构高可用流量防护组件之微服务保护

SpringCloud Alibaba :Sentinel 流量控制组件

分布式限流框架 - Sentinel

Sentinel介绍

阿里开源分布式限流框架 -Sentinel Go 0.3.0 发布,支持熔断降级能力