一、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