簡體   English   中英

線程池工作者不堪重負,使可運行程序崩潰

[英]Thread Pool Workers Overwhelmed With Runnables Crashing the JVM

簡要

我正在運行一個多線程tcp服務器,該服務器使用帶有無限制Runnable隊列的固定線程池。 客戶端將可運行對象分派到池中。

在我的壓力測試方案中,有600個客戶端嘗試登錄到服務器,並立即將消息同時廣播到其他每個客戶端並且一直重復到無盡,並且沒有休眠 (現在,客戶端只是丟棄傳入的消息)。 使用為堆內存保留1GB的四核以及年輕一代和老一代的並行GC,服務器會在20分鍾后崩潰,並出現OOM異常。 監視垃圾收集器表明,保有期限的一代正在緩慢增加,而完整的GC僅釋放了一小部分內存。 完整堆的快照顯示,老一代幾乎完全被Runnable(及其外發引用)占用。

似乎工作線程無法比客戶端將其排隊等待執行的速度更快地完成可運行對象的運行(對於服務器的每個傳入“事件”,服務器將創建599個可運行對象,因為有600-1個客戶端-假設他們當時都已登錄)。

有人可以幫我構思一下如何處理不堪重負的線程池工作者的策略嗎?

  • 如果我綁定隊列,應該執行什么策略來處理拒絕執行?
  • 如果我增加堆的大小,那不是只會延長OOM異常時間嗎?
  • 可以進行計算以度量Runnable聚合中完成的工作量。 也許此度量可以用作鎖定機制的基礎,以協調客戶的調度工作?
  • 當服務器不堪重負時,客戶應該經歷什么反應?

1)不要使用無界隊列。 我不能告訴你界限應該是多少。 您的負載測試應為您提供該問題的答案。 無論如何,使邊界可配置:至少可以動態地配置,更好地但仍適用於某些負載測量。

2)您沒有告訴我們客戶端如何提交他們的請求,但是如果涉及到HTTP,則已經有一個狀態代碼用於過載情況: 503 Service Unavailable

我建議您限制隊列的容量,並在發布者上“回推”以停止它的發布或優雅地丟棄請求。 您可以執行前一個b,使Queue塊填滿。

您應該能夠根據網絡帶寬和消息大小來計算最大吞吐量。 如果您獲得的資源不足,我會考慮更改服務器分配數據的方式。

另一種方法是使您的消息處理效率更高。 您可以讓每個客戶端的每個讀取線程直接寫入偵聽客戶端。 這避免了顯式隊列的需要(您可能將Socket中的緩沖區視為字節隊列),並將速度限制為服務器可以處理的速度。 它也不會在負載下使用更多的內存(比空閑時更多)

使用這種方法,您可以達到網絡帶寬可以處理的最高消息速率。 (即使使用10 Gig-E網絡也是如此)這將瓶頸轉移到其他地方,這意味着您仍然有問題,但是服務器不應出現故障。

順便說一句:如果您使用直接ByteBuffers,則可以在不創建垃圾且堆空間最少的情況下執行此操作。 例如,每個客戶端大約1 KB的堆。

您必須以某種方式限制傳入的請求,並且執行該請求的機制應取決於您要執行的工作。 其他任何事情都只會在足夠的負載下導致OOM,從而使您容易遭受DOS攻擊(甚至是無意的攻擊)。

從根本上講,您有4個選擇:

  1. 讓客戶等到您准備好接受他們的請求之前
  2. 積極拒絕客戶請求,直到您准備接受新請求
  3. 當客戶端尚未准備好接收請求時,嘗試訪問服務器時允許客戶端超時
  4. 上述策略的2或3的混合。

正確的策略取決於您的真實客戶在各種情況下的反應-是更好地讓他們(可能(無限期地)無限期地等待),還是更好地讓他們迅速知道自己的工作除非再次嘗試才能完成?后來?

無論采用哪種方式,都需要能夠計算當前排隊的任務數,並添加延遲,完全阻止或根據隊列中的項目數返回錯誤條件。

一個簡單的阻塞策略可以通過使用BlockingQueue實現來實現。 但是,這並不能提供特別精細的控制。

或者,您可以使用信號量來控制向隊列中添加任務的許可,如果您要應用輕微的限制,則具有提供tryAcquire(long timeout,TimeUnit unit)方法的優點。

無論哪種方式,都不要讓為客戶端提供服務的線程無限制地增長,否則,由於其他原因,您最終只會獲得OOM!

聽起來好像您在進行負載測試。 我會確定您認為“可接受的重負載”。 您期望單個客戶端產生的最大流量是多少? 然后加倍。 或三倍。 或按類似的方式縮放。 使用此閾值可限制或拒絕使用此帶寬的客戶端。

這有很多好處。 首先,它為您提供確定服務器負載(每台服務器的用戶)所需的分析類型。 其次,它為您提供了抵御DDOS攻擊的第一道防線。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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