前因:因為本系統中,有大數據高並發的場景。在向下游系統發送請求的時候,需要限流。否則會造成下游系統的堵塞。
實現方案1:
Thread.sleep(ms).
優點:簡單粗暴,一行代碼搞定
缺點:有點low,萬一線程被搶了,無法喚醒怎么辦
實現方案2:
Guava的RateLimiter類
優點:簡單實用,滿足簡單業務場景的需求。2行代碼就能搞定
缺點:功能還是比較簡單,限流方案限定在秒級
實現方案3:
RXJava的flowable
說明:比RateLimiter復雜,但是功能強大。還沒仔細研究過
所以綜合考慮,使用Guava的RateLimiter類是一個比較好的解決方案,下面附上2篇資料:
1.http://ifeve.com/guava-ratelimiter/
2.https://www.cnblogs.com/f-zhao/p/7210158.html
注意要點:RateLimiter 有一個有趣的特性是「前人挖坑后人跳」,也就是說 RateLimiter 允許某次請求拿走超出剩余令牌數的令牌。這就會造成rateLimiter.acquire()這個取令牌的方法,第一次取的時候,肯定是秒回的,不會任何停頓。
所以rateLimiter.acquire()一定要放在業務邏輯的最前面,最前面,最前面(重三遍)。我寫的時候以為和Thread.sleep()一樣是每次都會停的,結果放在方法最后面,前2次方法執行就沒限流效果了。