限流 – 限流注解組件開發(fā)
限流概述
系統(tǒng)存在服務上限,流量超過服務上限會導致系統(tǒng)卡死、崩潰。
限流:為了在高并發(fā)時系統(tǒng)穩(wěn)定可用,犧牲或延遲部分請求流量以保證系統(tǒng)整體服務可用。
限流算法
固定窗口計數(shù)
將時間劃分為多個窗口;
在每個窗口內每有一次請求就將計數(shù)器加一;
如果計數(shù)器超過了限制數(shù)量,則本窗口內所有的請求都被丟棄當時間到達下一個窗口時,計數(shù)器重置。
滑動窗口計數(shù)
將時間劃分為多個區(qū)間;
在每個區(qū)間內每有一次請求就將計數(shù)器加一維持一個時間窗口,占據(jù)多個區(qū)間;
每經(jīng)過一個區(qū)間的時間,則拋棄最老的一個區(qū)間,并納入最新的一個區(qū)間;
如果當前窗口內區(qū)間的請求計數(shù)總和超過了限制數(shù)量,則本窗口內所有的請求都被丟棄。
漏桶
將每個請求視作"水滴"放入"漏桶"進行存儲;
"漏桶"以固定速率向外"漏"出請求來執(zhí)行如果"漏桶"空了則停止"漏水";
如果"漏桶"滿了則多余的"水滴"會被直接丟棄。
令牌桶
令牌以固定速率生成;
生成的令牌放入令牌桶中存放,如果令牌桶滿了則多余的令牌會直接丟棄,當請求到達時,會嘗試從令牌桶中取令牌,取到了令牌的請求可以執(zhí)行;
如果桶空了,那么嘗試取令牌的請求會被直接丟棄。
漏桶和令牌桶對比
兩者實際上是相同的
在實現(xiàn)上是相同的基本算法,描述不同。
給定等效參數(shù)的情況下,這兩種算法會將完全相同的數(shù)據(jù)包視為符合或不符合。
兩者實現(xiàn)的屬性和性能差異完全是由于實現(xiàn)的差異造成的,即它們不是源于底層算法的差異。
漏桶算法在用作計量時,可以允許具有抖動或突發(fā)性的一致輸出數(shù)據(jù)包流,可用于流量管制和整形,并且可以用于可變長度數(shù)據(jù)包。
參考:
漏桶 - wikipedia
令牌桶 - wikipedia
相關閱讀:
分布式服務限流實戰(zhàn),已經(jīng)為你排好坑了
接口限流算法總結 - 穿林度水
限流注解組件實現(xiàn)
利用 Spring 攔截器實現(xiàn)
使用方式:Controller 方法或類加上限流注解,請求到達攔截器時進行攔截處理
使用 Redis 記錄數(shù)據(jù),Lua 保證多個命令原子性執(zhí)行。
使用示例
@RestController @RequestMapping("/ratelimit/custom") @RateLimit(threshold = 10, rateLimiter = RateLimiterEnum.FIXED_WINDOW, time = 10, timeUnit = TimeUnit.SECONDS) public class RateLimitController { ? ?@GetMapping("/fixed/window") ? ?@RateLimit(threshold = 10, rateLimiter = RateLimiterEnum.FIXED_WINDOW, time = 10, timeUnit = TimeUnit.SECONDS) ? ?public ResponseResult<String> fixedWindow(Long id) { ? ? ? ?id += RandomUtil.randomLong(); ? ? ? ?log.info("custom:fixedWindow:{}", id); ? ? ? ?return ResponseResult.success("custom:fixedWindow:" + id); ? ?} }
限流注解?
RateLimit.java
支持不同類型緩存 key:?
key() + keyType()
支持使用不同限流算法:?
rateLimiter()
限流流量閾值設置:?
threshold()
限流時長設置:?
time() + timeUnit()
限流攔截器處理?RateLimitInterceptor.java
限流算法 lua 腳本
固定窗口:?fixed_window_rate_limiter.lua
滑動窗口:?sliding_window_rate_limiter.lua
漏桶:?leaky_bucket_rate_limiter.lua
令牌桶:?token_bucket_rate_limiter.lua
其他
demo 地址:https://github.com/EastX/java-practice-demos/tree/main/demo-ratelimit
推薦閱讀:
限流 - JavaGuide
架構之高并發(fā):限流 - pdai
作者:EastX
原文鏈接:https://www.dianjilingqu.com/602395.html