如何設計服務接口API限流功能?
1 限流目的限流目的是對系統進行保護。當訪問量激增,超過系統可以承受的流量,則需要把超出的流量擋住,不進行業務邏輯直接返回。
2 預估系統流量上限采用壓測方法。對某個接口進行壓測,逐步調高并發量和持續時間,達到系統瓶頸時(錯誤率高,響應時間長)記錄下并發量,這個值就是當前系統流量上限。
3 限流方案3.1 系統維度從系統維度來看可以分為單機限流和集群限流兩種方式。
單機限流是對每一臺機器限流,假設每臺機器限流100QPS,集群有10臺機器,那么整個集群有1000QPS能力。可以使用Guava RateLimiter、Java并發包Semaphore實現單機限流。
集群限流是對整個集群進行限流,比如預估整個集群能力有1000QPS,還有一種場景是限次,比如整個集群只能調用第三方接口多少次??梢允褂肦edis實現全局限流。
3.2 方法維度限流常用方法有以下三種:
計數器法維護一個計數器,這個計數器有一個時間窗口,在當前時間窗口,每當一個新請求到來時,計數器自增,當計數器自增達到設置的上限時,不再提供服務?;瑒拥较乱粋€時間窗口時,計數器重置。這種方法的特點是簡單,但是在時間窗口臨界點,可能會出現超出流量的問題。
漏桶算法漏桶算法強制一個常量的輸出速率而不管輸入數據流的突發性。當輸入空閑時,該算法不執行任何動作,就像用一個底部開了個洞的漏桶接水一樣,水進入到漏桶里,桶里的水通過下面的孔以固定的速率流出。當水流入速度過大會直接溢出。
令牌桶算法我推薦這種方法。一個容量固定的桶,以一個恒定的速率產生令牌,如果桶內的令牌滿了則多余的令牌會被丟棄。每當請求進來時,先去桶內拿一個令牌,桶內的令牌拿完了,則必須等待桶內產生令牌才能允許后續的請求(或者直接拒絕)。由于桶內可以堆積一定的令牌(一般為桶容量),所以令牌桶算法優點是可以允許一定量的流量高峰。
Guava提供了限流工具RateLimiter基于令牌桶完成限流。也可以通過編寫Lua腳本通過Redis實現全局令牌桶。