億級流量網站架構核心技術:限流詳解之節流
上接聊聊高并發系統之限流特技-1、聊聊高并發系統之限流特技-2,本篇摘自《億級流量網站架構核心技術》第四章 限流詳解,在之前兩篇文章的基礎上增加了節流部分。
有時候我們想在特定時間窗口內對重復的相同事件最多只處理一次,或者想限制多個連續相同事件最小執行時間間隔,那么可使用節流(Throttle)實現,其防止多個相同事件連續重復執行。節流主要有如下幾種用法:throttleFirst、throttleLast、throttleWithTimeout。
1. throttleFirst/throttleLast
throttleFirst/ throttleLast是指在一個時間窗口內,如果有重復的多個相同事件要處理,則只處理***個或***一個。其相當于一個事件頻率控制器,把一段時間內重復的多個相同事件變為一個,減少事件處理頻率,從而減少無用處理,提升性能。
如上圖所示,throttleFirst在一個時間窗口內只會處理該時間窗口內的***個事件。
而throttleLast會處理該時間窗口內的***一個事件。
一個場景是網頁中的resize、scroll和mousemove 事件,當我們改變瀏覽器大小時會觸發resize事件,而滾動頁面元素時會觸發scroll事件。當我們快速連續執行這些操作時會連續觸發這些事件,那么可能因造成UI反應慢、瀏覽器卡頓,因此節流就派上用場了。對于前端開發可以使用jquery-throttle-debounce-plugin實現,而Android開發可以使用RxAndroid實現。
2 throttleWithTimeout
throttleWithTimeout也叫做debounce(去抖),限制兩個連續事件的先后執行時間不得小于某個時間窗口。
如上圖所示,throttleWithTimeout限制兩個連續事件的最小間隔時間窗口。throttleFirst/ throttleLast是基于決定時間做的處理,是以固定時間窗口為基準,對同一個固定時間窗口內的多個連續事件最多只處理一個。而throttleWithTimeout是基于兩個連續事件的相對時間,當兩個連續事件的間隔時間小于最小間隔時間窗口,就會丟棄上一個事件,而如果***一個事件等待了最小間隔時間窗口后還沒有新的事件到來,那么會處理***一個事件。
如搜索關鍵詞自動補全,如果用戶每錄入一個字就發送一次請求,而先輸入的字的自動補全會被很快到來的下一個字符覆蓋,那么會導致先期的自動補全是無用的。throttleWithTimeout就是來解決這個問題的,通過它來減少頻繁的網絡請求,避免每輸入一個字就導致一次請求。
使用RxJava 1.2.0實現的測試代碼。
- Observable
- .create(new Observable.OnSubscribe<Integer>(){
- @Override
- public void call(Subscriber<? super Integer> subscriber) {
- //next實現:Thread.sleep(millis); subscriber.onNext(i);
- next(subscriber, 1,0); //0ms
- next(subscriber, 2,50); //50ms
- next(subscriber, 3,50); //100ms
- next(subscriber, 4,30); //130ms
- next(subscriber, 5, 40); //170ms
- next(subscriber, 6,130); //300ms
- subscriber.onCompleted();
- }
- })
- .subscribeOn(Schedulers.newThread())
- .throttleWithTimeout(100,TimeUnit.MILLISECONDS)
- .subscribe(new Subscriber<Integer>() {
- ……
- @Override
- public void onNext(Integer i) {
- System.out.println("==" + i);
- }
- });
【本文是51CTO專欄作者張開濤的原創文章,作者微信公眾號:開濤的博客( kaitao-1234567)】