您好,登錄后才能下訂單哦!
本篇內容主要講解“java高并發場景下的限流策略是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“java高并發場景下的限流策略是什么”吧!
舉個比較簡單的例子,正常來說,一個員工A他每天能夠處理的工作是10個,突然某一天來了100個工作量,這時候,如果員工A還處理100個,只有一種可能,這個員工被壓垮。
如果我們能預先知道會有100個任務會來,我們通過增加員工數或定義消息隊列等等來臨時解決。
但是我們很多時候無法預料這些意外的。根據墨菲定律,壞事往往會接踵而來,有可能某個點掛了會引起全局的掛掉(雪崩)。因此我們不得不對我們的系統做一些保護措施。限流是其中之一。
針對秒殺這類場景,我們也可以做一些限流措施,而不影響到系統全局。
思路:限速,我們可能第一個想到的應該是,我通過一個計數器,進行技術,如果超過了計數器閥值,表示速度太快了。一秒一個計數器。
為了便于閱讀,我只截圖了主要的代碼片段。
這樣有個問題就是:粒度太大了,不均勻,針對1秒以下的,沒法辨析。
我們能不能把粒度拆細了,1秒拆成10個100毫秒。每一個100毫秒有一個計數器。了解TCP/IP的應該知道,TCP/IP為了增加傳輸速度和控制傳輸速度,有個叫“滑動窗口協議”。
就算拆得再細,也無法解決勻速限制速度的問題。
而且還有個臨界點問題,假如,一秒限制10個請求,在第1秒和第2秒之間,第1秒后半段時間10個請求,第2秒前半段10個請求,那第1秒后半段+第2秒前半段時間組成的一秒鐘里就有20個請求,沒有起到限速的作用。
有沒有更好的辦法呢?
在生活中,如果一桶有一個細眼,我們往里面裝水,可以看到水是一滴一滴勻速的下落的,哪我們能不能通過程序來實現這種方式呢。
思路:桶為容器,一滴水為一請求。如果桶滿了就拒絕請求,沒滿處理請求。
代碼片段
首先計算這次請求與上次請求來的時候,總共漏了多少水。
看一下桶里面還剩多少水,有沒有溢出。
如果溢出了拒絕請求,如果沒有添加當前一滴水。處理請求。
對于很多應用場景來說,除了要求能夠限制數據的平均傳輸速率外,還要求允許某種程度的突發傳輸。這時候漏桶算法可能就不合適了,令牌桶算法更為適合。
什么意思呢?就是說我服務前面閑了很久,突然來了很多請求(在桶的容量內),我得快速的把這些處理了。
思路:勻速的產生令牌,往桶里面丟,每次請求來,看是否有多余的令牌。如果有獲取令牌執行正常業務,偌沒有限速。
代碼片段
請求來的時候先計算目前放入桶中的令牌數,這里計算,就可以不用啟動一個線程勻速放置令牌了,這個叫惰性計算。
然后計算桶擁有的令牌數。然后獲取令牌。做拒絕還是處理動作。
以上代碼,可在Github查看。
https://github.com/hirudy/java_lib/tree/master/src/main/java/com/hirudy/limiter
安利大家一個高效的限速器。
google的基礎庫guava中包含了一個基于令牌桶的限速器RateLimiter。使用也很簡單。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。