簡體   English   中英

Java池連接優化

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM