高并发解决方案限流技术-----使用RateLimiter实现令牌桶限流
1,RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技,并且根据系统的实际情况来调整生成token的速率。
通常可应用于抢购限流防止冲垮系统;限制某接口、服务单位时间内的访问量,譬如一些第三方服务会对用户访问量进行限制;限制网速,单位时间内只允许上传下载多少字节等。
guava的maven依赖
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>25.1-jre</version> </dependency>
2,令牌桶的原理,有一个独立线程一直以一个固定的速率往桶中存放令牌
客户端去桶中获取令牌,获取到令牌,就可以访问,获取不到,说明请求过多,需要服务降级。
3,
package com.aiyuesheng.controller; import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.aiyuesheng.hystrix.OrderHystrixCommand; import com.aiyuesheng.service.OrderService; import com.aiyuesheng.utils.LimitService; import com.alibaba.fastjson.JSONObject; import com.google.common.util.concurrent.RateLimiter; @RestController public class Index {// 令牌桶:1.0 表示 每秒中生成1个令牌存放在桶中 RateLimiter rateLimiter = RateLimiter.create(1.0); @Autowired private OrderService orderService; //令牌桶限流 @RequestMapping("/searchCustomerInfoByRateLimiter") public Object searchCustomerInfoByRateLimiter() { // 1.限流判断 // 如果在0.5秒内 没有获取不到令牌的话,则会一直等待 System.out.println("生成令牌等待时间:" + rateLimiter.acquire()); boolean acquire = rateLimiter.tryAcquire(500, TimeUnit.MILLISECONDS); // 每次发送请求,愿意等待0.5秒,如果设为1秒,每次都能查询成功,因为没秒中都会放入一个令牌到桶中 if (!acquire) { System.out.println("稍后再试!"); return "稍后再试!"; } // 2.如果没有达到限流的要求,直接调用接口查询 System.out.println(orderService.searchCustomerInfo()); return orderService.searchCustomerInfo(); } }