Sentinel 限流的原理与应用

172 阅读3分钟

应用背景

Sentinel提供了丰富的功能特性,如流量控制异常熔断集群限流速率控制等。此外,Sentinel也提供了丰富的数据采集如RPCHTTP以及API Gateway等。

环境配置

引入pom依赖

<!--nacos依赖-->
<dependency>
		<groupId>com.alibaba.cloud</groupId>
		<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
		<groupId>com.alibaba.cloud</groupId>
		<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

<!--sentinel-->
<dependency>
		<groupId>com.alibaba.cloud</groupId>
		<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
		<groupId>com.alibaba.csp</groupId>
		<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
		<groupId>com.alibaba.csp</groupId>
		<artifactId>sentinel-transport-simple-http</artifactId>
		<version>1.8.1</version>
</dependency>
<dependency>
		<groupId>org.hibernate.validator</groupId>
		<artifactId>hibernate-validator</artifactId>
		<version>6.0.18.Final</version>
</dependency>

配置文件

spring:
  application:
    name: seckill-good # 项目名称
  profiles:
    active: dev # 开发环境
  cloud:
    nacos:
      discovery:
        server-addr: xxx:8848 # 注册中心的地址
      config:
        file-extension: yml # 文件后缀名
    sentinel:
      eager: true
      transport:
        dashboard: xxx:8080
        port: 8719

配置客户端

  1. 下载 jar 文件
  2. 运行以下后,输入http://localhost:8080,打开客户端
  3. 若是学习sentinel,强烈将sentinel运行在本地;

java -jar sentinel-dashboard-1.8.1

流量限制的使用

虽然Sentinel提供了丰富的功能特性,但我们当下需要重点关注的是流量控制部分。所谓流量控制,其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性

请求接口添加 @SentinelResourse 接口

@GetMapping("/{activityId}/list/{itemId}")
@SentinelResource((value = "GetSeckillGood")
public BaseResponse<SeckillGoodResponse> getSeckillGood(@RequestHeader(value = "TokenInfo") Long userId,
														@PathVariable Long activityId,
														@PathVariable Long itemId,
														@RequestParam(required = false) Long version) {
	return seckillGoodService.getSeckillGood(userId, activityId, itemId, version);
}

客户端新增流控规则

测试

使用apifox启动20个线程进行测试,并不会全部成功

常见的限流策略和实现方式

限流策略

直接拒绝:对于过多的流量,直接拒绝服务即可;

异步削峰:将用户请求放入消息队列,通过异步处理的方式进行削峰,避免瞬间流量对系统造成冲击。不过要考虑队列满载和队列任务超时的情况‘

特权请求:即在服务资源紧缺的情况下,流量对部分特权用户放开,而对一般用户选择性关闭,比如你充了钱,那你可能就会享受和别人不一样的服务。

实现方式

计数器

当请求进来时,计数器加1,请求完毕后,计数器减1,当计数器的值超过阈值时,则将拒绝服务。

队列算法

待处理列表是一个队列,按FIFO算法处理到来的请求;

可以使用优先级队列,带权重的任务队列优化,处理不同的资源请求

带权重的任务队列:根据权重每次从某个队列中取出不同数量的请求,防止低权级的队列饿死

漏桶算法

水进入漏桶,就有一定的出水速率(响应速率),当水的流入速度大于溢出速度时(访问频率大于响应速率),然后就可以拒绝请求了。

出水速率是固定的参数,所以网络空闲的时候,也不能将访问频率突发到端口速率。

令牌桶算法

随着时间流逝,系统会按恒定 1/QPS 时间间隔(如果 QPS =100,则间隔是10ms)往桶里加入 Token (想象和漏洞漏水相反,有个水龙头在不断的加水),如果桶已经满了就不再加了。新请求来临时,会各自拿走一个 Token,如果没有 Token 可拿了就阻塞或者拒绝服务

令牌桶的另外一个好处是可以方便的改变速度一旦需要提高速率,则按需提高放入桶中的令牌的速率。一般会定时(比如100毫秒)往桶中增加一定数量的令牌,有些变种算法则实时的计算应该增加的令牌的数量。