学习空间编程语言爱好者Java服务器端编程

服务限流之令牌桶算法

2021-12-21  本文已影响0人  迦叶_金色的人生_荣耀而又辉煌

上一篇 <<<服务限流之滑动窗口计数
下一篇 >>>服务限流之漏桶算法


令牌桶算法是一个存放固定容量令牌的桶,按照固定速率往桶里添加令牌。
令牌桶算法的描述如下:
假设限制2r/s,则按照500毫秒的固定速率往桶中添加令牌;
桶中最多存放b个令牌,当桶满时,新添加的令牌被丢弃或拒绝;
当一个n个字节大小的数据包到达,将从桶中删除n个令牌,接着数据包被发送到网络上;
如果桶中的令牌不足n个,则不会删除令牌,且该数据包将被限流(要么丢弃,要么缓冲区等待)。

<dependencies>
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>25.1-jre</version>
    </dependency>
</dependencies>

/*
 * RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技,并且根据系统的实际情况来调整生成token的速率。
 * 使用RateLimiter 实现令牌通方式限流
 */
@RestController
public class IndexController {
   @Autowired
   private OrderService orderService;
   // create 方法中传入一个参数 以每秒为单位固定的速率值 1r/s 每秒中往桶中存入一个令牌
   RateLimiter rateLimiter = RateLimiter.create(100); // 独立线程

   // 相当于该接口每秒钟时间 只能支持一个客户端访问
   @RequestMapping("/addOrder")
   public String addOrder() {
      // 1.限流处理 限流正常要放在网关 客户端从桶中获取对应的令牌,为什么返回double结果,这个结果表示 从桶中拿到令牌等待时间.
      // 2. 如果获取不到令牌,就会一直等待.设置服务降级处理(相当于配置在规定时间内如果没有获取到令牌的话,直接走服务降级。)
      // double acquire = rateLimiter.acquire();
      //
      // System.out.println("从桶中获取令牌等待的时间:" + acquire);
      // 如果在500毫秒内如果没有获取到令牌的话,则直接走服务降级处理
      boolean tryAcquire = rateLimiter.tryAcquire(500, TimeUnit.MILLISECONDS);
      if (!tryAcquire) {
         System.out.println("别抢了, 在抢也是一直等待的, 还是放弃吧!!!");
         return "别抢了, 在抢也是一直等待的, 还是放弃吧!!!";
      }
      // 2. 业务逻辑处理
      boolean addOrderResult = orderService.addOrder();
      if (addOrderResult) {
         System.out.println("恭喜您,抢购成功! 等待时间:" + rateLimiter.acquire());
         return "恭喜您,抢购成功!";
      }
      return "抢购失败!";
   }
}

推荐阅读:
<<<高并发架构的整体思路
<<<一个网站访问慢的真正原因
<<<高并发情况下,接口的代码会存在哪些问题
<<<压缩静态资源减少带宽传输的方式
<<<动静分离架构模式
<<<缓存策略汇总
<<<后端服务的雪崩效应及解决思路
<<<服务的隔离、降级和熔断
<<<服务限流之计数器方式
<<<服务限流之滑动窗口计数
<<<服务限流之漏桶算法
<<<漏桶算法和令牌桶算法的区别
<<<自定义封装限流算法
<<<应用级限流
<<<接入层限流

上一篇下一篇

猜你喜欢

热点阅读