[英]Java pooling connection optimization
在Java中,哪些公共指南/建議配置一個http連接池,以支持對同一服務器的大量並發http調用? 我的意思是:
(我正在使用Apache http組件4.3,但我可以探索新的解決方案)
為了更清楚,這是我的情況:
我開發了一個REST資源,需要對AWS CloudSearch執行大約10次http調用,以便獲得在最終結果中收集的搜索結果(我實際上無法通過單個查詢獲得)。 整個操作必須少於0.25秒。 所以,我在10個不同的線程中並行運行http調用。 在benchamarking測試期間,我注意到很少有並發請求,5,我的目標已達成。 但是,將並發請求增加到30,由於連接時間大約需要1秒,因此性能會大幅下降。 相反,幾乎沒有並發請求,連接時間大約為150毫秒(更確切地說,第一個連接需要1秒,所有以下連接大約需要150毫秒)。 我可以確保CloudSearch在不到15毫秒內返回響應,因此我的連接池中存在問題。
謝謝!
最適合您實現的線程/連接數取決於該實現(您沒有發布),但這里有一些指令:
如果這些線程永遠不會阻塞,那么你應該擁有與核心一樣多的線程(Runtime.availableCores(),這將包括超線程核心)。 僅僅因為超過100%的CPU使用率是不可能的。
如果您的線程很少阻塞,則核心* 2是基准測試的良好開端。
如果您的線程經常阻塞,您絕對需要使用各種設置對應用程序進行基准測試,以便為您的實現,操作系統和硬件找到最佳解決方案。
現在最優化的情況顯然是第一個,但要實現這一點,您需要盡可能多地從代碼中刪除阻塞。 如果您在非阻塞模式下使用NIO包(這不是Apache包的方式),Java可以為IO操作執行此操作。
然后,您有一個線程在選擇器上等待,並在任何數據准備好發送或讀取后立即喚醒。 然后,該線程僅將數據從其源復制到目標並返回到選擇器。 在讀取(傳入數據)的情況下,該目標是阻塞隊列, 核心數量的線程在其上等待。 其中一個線程將提取所接收的數據並對其進行處理,現在沒有任何阻塞。
然后,您可以使用阻塞隊列的長度來調整任務和硬件合理的並行請求數。
第一個連接需要> 1秒,因為它實際上必須通過DNS查找地址。 所有其他連接暫時擱置,因為這樣做兩次沒有意義。 您可以通過調用IP(如果與負載均衡器通信可能不好)或通過初始請求“預熱”連接來規避這一點。 之后的任何新連接都將使用緩存的DNS結果,但仍需要執行其他初始化,因此盡可能多地重用連接將大大減少延遲。 使用NIO,這是一項非常簡單的任務。
此外還有HTTP多請求 ,即:您建立一個連接但在一個請求中請求多個URL並通過“同一行”獲得多個響應。 這大大減少了連接開銷,但需要服務器支持。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.