上一篇 <<<服務(wù)限流之滑動窗口計(jì)數(shù)
下一篇 >>>服務(wù)限流之漏桶算法
令牌桶算法是一個存放固定容量令牌的桶,按照固定速率往桶里添加令牌瞧甩。
令牌桶算法的描述如下:
假設(shè)限制2r/s滞伟,則按照500毫秒的固定速率往桶中添加令牌;
桶中最多存放b個令牌,當(dāng)桶滿時,新添加的令牌被丟棄或拒絕;
當(dāng)一個n個字節(jié)大小的數(shù)據(jù)包到達(dá)儒将,將從桶中刪除n個令牌,接著數(shù)據(jù)包被發(fā)送到網(wǎng)絡(luò)上默终;
如果桶中的令牌不足n個椅棺,則不會刪除令牌,且該數(shù)據(jù)包將被限流(要么丟棄齐蔽,要么緩沖區(qū)等待)。
<dependencies>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>25.1-jre</version>
</dependency>
</dependencies>
/*
* RateLimiter是guava提供的基于令牌桶算法的實(shí)現(xiàn)類床估,可以非常簡單的完成限流特技含滴,并且根據(jù)系統(tǒng)的實(shí)際情況來調(diào)整生成token的速率。
* 使用RateLimiter 實(shí)現(xiàn)令牌通方式限流
*/
@RestController
public class IndexController {
@Autowired
private OrderService orderService;
// create 方法中傳入一個參數(shù) 以每秒為單位固定的速率值 1r/s 每秒中往桶中存入一個令牌
RateLimiter rateLimiter = RateLimiter.create(100); // 獨(dú)立線程
// 相當(dāng)于該接口每秒鐘時間 只能支持一個客戶端訪問
@RequestMapping("/addOrder")
public String addOrder() {
// 1.限流處理 限流正常要放在網(wǎng)關(guān) 客戶端從桶中獲取對應(yīng)的令牌丐巫,為什么返回double結(jié)果谈况,這個結(jié)果表示 從桶中拿到令牌等待時間.
// 2. 如果獲取不到令牌,就會一直等待.設(shè)置服務(wù)降級處理(相當(dāng)于配置在規(guī)定時間內(nèi)如果沒有獲取到令牌的話递胧,直接走服務(wù)降級碑韵。)
// double acquire = rateLimiter.acquire();
//
// System.out.println("從桶中獲取令牌等待的時間:" + acquire);
// 如果在500毫秒內(nèi)如果沒有獲取到令牌的話,則直接走服務(wù)降級處理
boolean tryAcquire = rateLimiter.tryAcquire(500, TimeUnit.MILLISECONDS);
if (!tryAcquire) {
System.out.println("別搶了缎脾, 在搶也是一直等待的祝闻, 還是放棄吧!R挪ぁ联喘!");
return "別搶了华蜒, 在搶也是一直等待的, 還是放棄吧;碓狻0认病!";
}
// 2. 業(yè)務(wù)邏輯處理
boolean addOrderResult = orderService.addOrder();
if (addOrderResult) {
System.out.println("恭喜您蓖谢,搶購成功! 等待時間:" + rateLimiter.acquire());
return "恭喜您捂蕴,搶購成功!";
}
return "搶購失敗!";
}
}
推薦閱讀:
<<<高并發(fā)架構(gòu)的整體思路
<<<一個網(wǎng)站訪問慢的真正原因
<<<高并發(fā)情況下,接口的代碼會存在哪些問題
<<<壓縮靜態(tài)資源減少帶寬傳輸?shù)姆绞?/a>
<<<動靜分離架構(gòu)模式
<<<緩存策略匯總
<<<后端服務(wù)的雪崩效應(yīng)及解決思路
<<<服務(wù)的隔離闪幽、降級和熔斷
<<<服務(wù)限流之計(jì)數(shù)器方式
<<<服務(wù)限流之滑動窗口計(jì)數(shù)
<<<服務(wù)限流之漏桶算法
<<<漏桶算法和令牌桶算法的區(qū)別
<<<自定義封裝限流算法
<<<應(yīng)用級限流
<<<接入層限流