2012-09-01 49 views
0

我看到了奇怪的行爲,我不知道如何獲得進一步的洞察,並希望有人能夠提供幫助。Tomcat表現得好像不是線程請求,導致響應時間慢

背景:我有一個需要很長時間才能返回結果的查詢,所以不要讓用戶根據請求直接等待數據我通過Timer對象定期執行此查詢並將結果存儲在靜態變量中。因此,當用戶請求數據時,我總是從靜態變量中抽取數據,因此使得響應幾乎是即時的。到現在爲止還挺好。

問題:但是,我看到的行爲是,如果我在後臺(定時器)請求開始查詢數據時對數據發出請求,則我的用戶請求會等待數據返回在響應之前 - 迫使用戶等待。就好像tomcat與線程同步運行(我知道它不是 - 它看起來就是這樣)。

這是在一個生產環境中,大部分情況下,一切都很好,但對於用戶來說,有時候站點只是爲他們掛起,他們覺得它是不可靠的(就某種意義而言)。

我做了什麼:因爲數據的請求是靜態方法,所以我認爲「哈哈!線程被同步,導致延遲!」所以我把所有的靜態方法都拉出來,取消了syncronization並強制每次調用實例化它自己的對象來檢索數據(以保證線程安全)。信號量沒有與靜態變量同步。

我也安裝了javamelody試圖獲得一些洞察到現在發生了什麼,但到目前爲止沒有新的。我已經注意到很多(大部分)線程處於「等待」狀態,但它們對於用戶和CPU時間也有0ms,所以不要認爲它指向任何東西(?)。

運行Tomcat 5.5(無阿帕奇層),支柱2,Java 1.5的

如果任何人有任何想法,爲什麼一個簡單的要求,以一個靜態變量掛起較長的後臺進程,我真的很感激!或者,如果你知道我如何能夠獲得洞察力,那也會很棒。

謝謝!

+0

聽起來好像有一個'synchronized'的地方,或阻止你的對象調用停止請求處理的地方。(如果沒有,它不會是線程安全的) – nos

+0

我同意,它看起來像但這兩個調用是完全分開的,它們唯一共同的是一個結果更新靜態變量,而另一個讀取它(和順序對我無關緊要),每個調用的方法都是完全獨立的。這是我的困惑的本質 - 我看不出兩個獨立的tomcat請求是如何相互依賴的,當它們唯一共同的東西是一個時,非同步的(這是確定的)靜態變量。 – somecity

+0

這個靜態變量是什麼類型,你用它做什麼? – nos

回答

0

一個可能的解釋是,由於長時間運行的查詢導致數據庫鎖定(或其他),線程實際上在數據庫級別阻塞。

找出發生了什麼的方法是準確找出被阻塞的線程阻塞的位置。線程轉儲可以通過向JVM發送SIGQUIT(或等價物)來生成,並且包含所有Java線程堆棧的堆棧跟蹤。或者,您可以通過附加調試器等獲得相同的信息(以及更多)。無論哪種方式,每個堆棧頂部框架的類名和行號應該允許您查看源代碼並找出(至少)究竟是在進行什麼樣的鎖定或阻塞。

+0

感謝斯蒂芬爲此...我在日食,但進程是在tomcat。這是沒有斷點,我可以使用,而tomcat沒有響應。你的意思是我應該在每次調用的時候對每個線程做整個堆棧跟蹤嗎?似乎我的下一個問題會試圖從所有數據中理解。 – somecity

+0

Eclipse調試器應該允許您檢查Tomcat服務器的堆棧。您可能必須首先將其從調試器中暫停。或者,從命令行運行Tomcat,併發送一個SIGQUIT。 –

+0

*「你的意思是我應該在每次調用的時候對每個線程做一個完整的堆棧跟蹤?」*。請重讀我寫的內容。 *「好像我的下一個問題會試圖從所有數據中理解。」*顯然(!!)你只需要爲典型的堆棧做這件事。但是,是的,你需要了解足夠的數據才能弄清楚發生了什麼。 (如果編程/調試非常簡單,他們可以用一半的薪水來做漢堡鰭......) –

0

對於那些想知道我最終找到VisualVM(http://visualvm.java.net/download.html)。這是完美的。我像通常一樣從eclipse運行Tomcat,它出現在VisualVM客戶端中。用鼠標右鍵單擊tomcat圖標,選擇線程轉儲,繁榮,我已經掌握了一切。

謝謝大家的幫助和指向正確方向的指針!