Coldfusion

JRun執行緒池配置

  • December 7, 2009

在過去 6 個月的大部分時間裡,我和我的團隊一直在努力保持集群 ColdFusion 應用程序的穩定,但收效甚微。我們轉向 SF,希望能找到一些 JRun 專家或新想法,因為我們似乎無法弄清楚。

設置:

兩個 ColdFusion 7.0.2 實例在 Windows Server 2003 下的 IIS 6 上使用 JRun 4(帶有最新更新)集群。兩個四核 CPU,8GB RAM。

問題:

不時地,通常每週一次,其中一個實例將完全停止處理請求。它沒有任何活動,我們必須重新啟動它。

我們所知道的:

每次發生這種情況時,JRun 的錯誤日誌總是充滿 java.lang.OutOfMemoryError: unable to create new native thread。

在閱讀了來自 Macromedia/Adobe 的 JRun 文件和許多令人困惑的部落格文章之後,我們或多或少地將其縮小到實例的 jrun.xml 中不正確/未優化的 JRun 執行緒池設置。

我們 jrun.xml 的相關部分:

<service class="jrun.servlet.jrpp.JRunProxyService" name="ProxyService">
   <attribute name="activeHandlerThreads">500</attribute>
   <attribute name="backlog">500</attribute>
   <attribute name="deactivated">false</attribute>
   <attribute name="interface">*</attribute>
   <attribute name="maxHandlerThreads">1000</attribute>
   <attribute name="minHandlerThreads">1</attribute>
   <attribute name="port">51003</attribute>
   <attribute name="threadWaitTimeout">300</attribute>
   <attribute name="timeout">300</attribute>
{snip}  
</service>

上週我啟用了 JRun 的指標記錄來收集與執行緒相關的數據。這是記錄一周後的數據摘要。

平均值:

{jrpp.listenTh}       1
{jrpp.idleTh}         9
{jrpp.delayTh}        0
{jrpp.busyTh}         0
{jrpp.totalTh}       10
{jrpp.delayRq}        0
{jrpp.droppedRq}      0
{jrpp.handledRq}      4
{jrpp.handledMs}   6036
{jrpp.delayMs}        0
{freeMemory}      48667
{totalMemory}    403598
{sessions}          737
{sessionsInMem}     737

最大值:

{jrpp.listenTh}       10
{jrpp.idleTh}         94
{jrpp.delayTh}         1
{jrpp.busyTh}         39
{jrpp.totalTh}       100
{jrpp.delayRq}         0
{jrpp.droppedRq}       0
{jrpp.handledRq}      87
{jrpp.handledMs}  508845
{jrpp.delayMs}         0
{freeMemory}      169313
{totalMemory}     578432
{sessions}          2297
{sessionsInMem}     2297

關於我們現在可以嘗試什麼的任何想法?

乾杯!


編輯 #1 -> 我忘了提及的事情:Windows Server 2003 Enterprise w/JVM 1.4.2(用於 JRun)

最大堆大小約為 1.4GB 是的。我們曾經有洩漏,但我們修復了它們,現在應用程序使用大約 400MB,很少更多。最大堆大小設置為 1200MB,所以我們沒有達到它。當我們確實有洩漏時,JVM 就會爆炸,實例會自行重啟。現在沒有發生這種情況,它只是停止處理傳入的請求。

我們認為這與這篇博文之後的執行緒有關: http ://www.talkingtree.com/blog/index.cfm/2005/3/11/NewNativeThread

拋出的 Java 異常是 OutOfMemory 類型,但實際上並不是說我們用完了堆空間,只是說它無法創建新執行緒。異常類型有點誤導。

基本上,部落格是說 500 作為 activeHandlerThreads 可能太高了,但我的指標似乎表明我們沒有接近讓我們感到困惑的地方。

好吧,在進入 JRun 配置細節之前,讓我們先看看一些更大的問題。

如果您在 JRun 錯誤日誌中收到 java.lang.OutOfMemoryError 異常,那麼您的記憶體不足。請不要對此表示贊同;-)。您沒有說您執行的是 32 位還是 64 位 Windows,但您確實說您有 8 GB 的 RAM,因此這會對答案產生一些影響。無論您執行的是 32 位還是 64 位 JVM(以及什麼版本)也會影響事情。所以這些是一些答案,可以幫助我們深入了解這一點。

無論如何,您的應用程序記憶體不足。由於以下一個或多個原因,它的記憶體不足:

  1. 您的應用程序正在洩漏記憶體。您的應用程序使用的某些對象會被持續引用,因此永遠不符合垃圾收集的條件;或者更糟 - 在每個請求上創建的一些新對像被另一個對象永久引用,因此永遠沒有資格進行垃圾收集。在這方面,正確的 J2EE 會話處理可能特別棘手。
  2. 處理每個並發請求(在配置的並發請求級別)所需的記憶體量超過了 JVM 堆中可用的記憶體量。例如,您有一個 1 GB 的堆大小,每個請求最多可以使用 10 MB。您的應用伺服器已調整為允許 150 個並發請求。(簡單的數字,我知道)。在這種情況下,如果您在負載下遇到 100 個或更多並發請求(如果每個請求都使用了完成請求所需的最大記憶體量),那麼您肯定會耗盡記憶體。

其他要記住的事情:在 32 位 Windows 上,32 位 JVM 只能分配大約 1.4 GB 的記憶體。如果 64 位 Windows 上的 32 位 JVM 的限制小於任何 32 位程序的理論最大 4 GB,我不記得了。

更新

我閱讀了通過 TalkingTree 連結的部落格文章以及該文章中連結的另一篇文章。我沒有遇到這種確切的情況,但我確實有以下觀察結果:JRUN 指標日誌記錄可能不會記錄您線上程使用高峰期引用的“最大值”。我認為它以固定的重複間隔記錄指標。這有助於向您展示應用程序的平穩、平均性能特徵,但它可能無法在錯誤情況開始發生之前擷取 JRUN 的狀態。

在不了解 JRUN 執行緒管理的內部工作原理的情況下,我仍然說它確實記憶體不足。也許它不是記憶體不足,因為您的應用程序需要在 JVM 堆上分配記憶體並且沒有可用的記憶體,但它記憶體不足,因為 JRUN 試圖創建另一個執行緒來處理傳入請求,而支持另一個執行緒所需的堆記憶體是’ t 可用——換句話說,執行緒不是空閒的——它們也需要堆記憶體。

您的選擇似乎如下:

  1. 減少您的應用程序在每個請求中使用的記憶體量,或者 -
  2. 實驗性地降低 JRUN 配置中執行緒調整參數的值,以使更多執行緒排隊等待處理,而不是同時變為可執行,或者 -
  3. 在 ColdFusion 管理員中減少同時請求的數量(請求調整頁面,欄位“同時模板請求的最大數量”)

無論您追求哪種選擇,我認為這裡的有效解決方案本質上都是實驗性的。你將不得不做出改變,看看它對應用程序有什麼影響。你有一個負載測試環境,對吧?

引用自:https://serverfault.com/questions/89841