在高併發系統中,我們經常遇到這樣的需求:系統產生大量的請求,但是這些請求實時性要求不高。我們就可以將這些請求合併,達到一定數量我們統一提交。最大化的利用系統性io,提公升系統的吞吐效能。
所以請求合併框架需要考慮以下兩個需求:
當請求收集到一定數量時提交資料
一段時間後如果請求沒有達到指定的數量也進行提交
我們就聊聊一如何實現這樣乙個需求。
我們就聊一聊實現這個東西的具體思路是什麼。希望大家能夠學習到分析問題,設計模組的一些套路。
底層使用什麼資料結構來持有需要合併的請求?
經過上面的分析,我們就有了這樣乙個資料結構:
private static class flushthreadimplements runnable
//外部提交資料的方法
public boolean add(item item)
//提供給外部的超時方法
public void timeout()
}//解除執行緒的阻塞
private void start()
//當前的資料是否大於提交的條件
private void flushondemand()
}//執行提交資料的方法
public void flush()catch (throwable e)}}
//根據資料的尺寸和時間間隔判斷是否提交
private boolean canflush()
@override
public void run()
flush();}}
}
如何實現定時提交呢?
通常我們遇到定時相關的需求,首先想到的應該是使用scheduledthreadpoolexecutor
定時來呼叫flushthread 的 timeout 方法,如果你想到的是thread.sleep()
...那需要再努力學習,多看原始碼了。
怎樣進一步的提公升系統的吞吐量?
我們使用的flushthread
實現了runnable
所以我們可以考慮使用執行緒池來持有多個flushthread
。
所以我們就有這樣的**:
public class flusher
for (int i = 0; i < threads; i++)
}// 對 index 取模,保證多執行緒都能被add
public boolean add(item item)
int mod = index.incrementandget() % len;
return flushthreads[mod].add(item);
}//上文已經描述
private static class flushthreadimplements runnable
}
面向介面程式設計,提公升系統擴充套件性:
public inte***ce processor
我們寫個測試方法測試一下:
//實現 processor 將 string 全部輸出
public class printoutprocessor implements processor
}
public class test
}}
執行的結果:
start flush12
3end flush
start flush45
67end flush
我們發現並沒有達到10個數字就觸發了flush。因為出發了超時提交,雖然還沒有達到規定的5
個資料,但還是執行了 flush。
如果我們去除thread.sleep(1000);
再看看結果:
start flush12
345end flush
start flush67
8910end flush
每5個數一次提交。完美。。。。
徒手擼框架--實現ioc
徒手擼框架--實現aop
併發程式設計下的Executor框架
executor是乙個介面,用於執行實現了runnable的任務 public inte ce executorexecutor介面可以將任務的提交與任務的實際執行解耦開來,也就是說 可以直接將任務集合作為引數傳遞給executor.execute 方法,由executor介面的execute方法決...
高併發環境下的限流策略
在開發高併發系統時,有很多手段來防止系統過載 快取 降級 限流。快取的目的是提公升系統訪問速度和增大系統的吞吐量,降級和限流的目的如下 降級 降級是當服務出問題或者影響到核心流程的效能時需要暫時遮蔽掉某些功能,等高峰或者問題解決後再開啟。降級一般有幾種實現手段,自動降級和人工降級 1 通過配置降級開...
高併發環境的下冪等操作
冪等就是多次重複提交執行與一次提交執行的結果影響一樣 在高併發的環境下,很頻繁就觸發多次請求 1.前端頁面多次提交 2.網路重發 系統bug重試 nginx重發3.乙個業務請求只對應乙個訂單號 1.select update 在update操作之前先執行select查詢操作,適用併發不多的場景 2....