一、Guava两种限流模式
原理:系统会以一个恒定的速度往桶里放入令牌,而如果请求需要被处理,则需要先从桶里获取一个令牌,当桶里没有令牌可取时,则拒绝服务。
稳定模式(SmoothBursty:令牌生成速度恒定),
渐进模式(SmoothWarmingUp:令牌生成速度缓慢提升直到维持在一个稳定值)
二、RateLimiter
//每秒放行20个请求
RateLimiter rateLimiter = RateLimiter.create(20);
@ApiOperation("下单-乐观加锁")
@RequestMapping(value = "/createOptimisticOrder/{stockId}", method = RequestMethod.GET)
@ResponseBody
public String createOptimisticOrder(@PathVariable String stockId) {
/**
* 阻塞式获取令牌
* 库存100,并发500 下同
* 结果:正常
* 库存扣100,下单100
*/
log.info("阻塞式获取令牌 限流:{}", rateLimiter.acquire());
/**
* 非阻塞式获取令牌
* 库存100,并发500 下同
* 结果:正常
* 库存扣100,下单100
*/
// if(!rateLimiter.tryAcquire(1, TimeUnit.SECONDS)){
// log.info("非阻塞式获取令牌 限流");
// return "购买失败,库存不足";
// }
return orderService.createOptimisticOrder(stockId);
}
-
阻塞式获取令牌:收到请求,若令牌桶里没有足够的令牌,就在这里阻塞住,等待令牌的发放。
-
非阻塞式获取令牌:收到请求,若令牌桶里没有足够的令牌,会尝试等待设置好的时间 T,其会自动判断在 T 后,该请求能不能拿到令牌,如果不能拿到,直接返回抢购失败。如果timeout设置为0,则等于阻塞时获取令牌。
这里使用:SmoothBursty