天天看點

國内首位中間件Oracle ACE:WebLogic執行線程耗盡解決方案

<b></b>

作者介紹

王超,國内第一位中間件oracle ace,東方宏達中間件技術總監,原oracle|bea 資深中間件現場支援工程師,14年現場支援工作經驗,weblogic 6.1/7.0/8.1/9.2/10.3/11g/12c、tuxedo技術認證專家。深厚的中間件架構規劃、性能調優、問題解決經驗,常年為為電信、金融等領域客戶提供現場技術支援。

1.1、概述 

weblogic伺服器執行線程耗盡後就不再響應後續請求,weblogic即出現挂起現象。

weblogic線程耗盡産生的原因有多種,一般而言線程耗盡是由于線程在争奪某種資源。當一種資源處于缺少狀态,比如資料庫jdbc連接配接池的達到最大連接配接數,就會導緻後續的業務線程都卡在等待擷取jdbc的連接配接上,最終導緻伺服器無法響應後續的服務請求。

1.2、常見線程耗盡原因 

weblogic伺服器線程耗盡,最常見的幾種原因如下:

weblogic、jdk自身的bug

業務系統中采用的開源軟體的bug

主機硬體到達上限瓶頸,無法承擔更多的負載

資料庫jdbc連接配接池耗光,後續業務線程無法擷取到可用jdbc連接配接而一直處于等待狀态

應用程式同步調用。比如業務線程a執行的過程中鎖定了資源1,而由于同步調用的原因導緻其他業務線程不得不一直無限等待資源1的鎖被釋放。

業務系統沒有使用weblogic線程池,而使用自定義的線程池。當自定義線程池全部被占用,就會導緻沒有線程可用于新工作。

線程都處于等待rjvm、rmi響應

應用配置不合理,比如設定了錯誤的jsp pagecheckseconds參數等

1.3、判斷條件 

在出現以下情況時懷疑weblogic伺服器線程耗盡:

伺服器不響應新的請求

請求逾時

請求處理的時間越來越長(其最終結果可能是挂起)

通常,伺服器挂起不會表現為伺服器崩潰,但伺服器挂起之後可能會崩潰。

1.4、收集資訊 

當伺服器挂起時,首先使用 java weblogic.admin t3://server:port ping 來 ping 該伺服器。如果伺服器能夠響應此 ping,則可能是應用程式所使用的線程池耗盡而不是伺服器自身。

weblogic server 在8.1版本之前使用“default”線程池響應用戶端服務請求,在9.0版本以後使用default (self-tuning)線程池響應用戶端服務請求。這些是在發生線程耗盡時應當檢查的線程池。通常情況下,用收集jvm的thread dump的辦法來分析線程池運作資訊。

linux / unix系統

任何weblogic版本均可使用 kill -3 建立診斷問題所需的 thread dump。確定在每個伺服器上執行幾次,每次間隔大約 3 到 5秒,以幫助診斷死鎖問題。

在weblogic 9.2版本或者是更高的版本中,可以直接通過使用jdk的jstack指令來收集thread dump資訊。

windows作業系統

任何weblogic版本均可使用 - 來建立診斷問題所需的 thread dump。確定在每個伺服器上執行幾次,每次間隔大約 3 到 5 秒,以幫助診斷死鎖問題。

1.5、實施步驟 

收集作業系統、weblogic運作相關基本資訊

收集出現線程耗盡時間段weblogic運作日志

采集thread dump

在伺服器上快速分析thread dump,初步定位線程耗盡問題

重新開機線程耗盡weblogic伺服器,使其盡快對外提供服務

将采集到的thread dump下載下傳到本地,進行詳細的離線分析

1.6、分析thread dump 

weblogic除了包含業務系統所使用的執行線程池以外,還包括listenthread線程池、socket reader線程池以及自定義線程池等等。由于weblogic軟體是非常複雜的企業軟體,是以在分析的時候,我們不但需要關注業務執行線程池,同時也需要關注其他線程池。weblogic線程池簡易圖示如下:

國内首位中間件Oracle ACE:WebLogic執行線程耗盡解決方案

thread dump線程轉儲是将目前jvm包含的所有的線程的運作狀态的一個映像,包含了:

各個線程的棧 (stacktrace)

線程目前的狀态

線程名字

線程号(tid)以及對應的native thread id (nid) 等資訊

分析weblogic伺服器線程耗盡的最有用的辦法是分析一系列 的thread dump。一系列 thread dump(一般每隔3 到 5 秒進行三個或更多 thread dump)可以幫助分析每個線程從一個 thread dump 到另一個 thread dump 過程中的狀态變化或所缺少的變化。weblogic伺服器線程耗盡導緻伺服器挂起後,伺服器的 thread dump 一般顯示線程狀态從第一個 thread dump 到最後一個 thread dump 中變化很小。

在 thread dump 中檢視的内容

所有請求都通過 listenthread 進入 weblogic server。如果 listenthread 丢失,就無法接收任何工作,是以也無法完成任何工作。确認在 thread dump 中存在 listenthread。listenthread 應當在 socketaccept 方法中。下面示例說明監聽線程 (listen thread) 的形式。

國内首位中間件Oracle ACE:WebLogic執行線程耗盡解決方案

socket reader 線程接受來自監聽線程隊列的傳入請求,并将該請求放入執行線程隊列。如果 thread dump 中沒有 socket reader 線程,則在某個地方存在導緻 socket reader 線程消失的錯誤。應當始終保持至少有三個 socket reader 線程。一個 socket reader 線程一般用于輪詢功能,另外兩個用于處理請求。下面是一個 thread dump 示例中的 socket reader 線程。

國内首位中間件Oracle ACE:WebLogic執行線程耗盡解決方案

通常,業務代碼使用的是weblogic預設的執行線程池,在weblogic 8.1之前以“default”命名,在9.x以後以“weblogic.kernel.default(self-tuning)”命名。檢視執行線程的狀态,主要看thread dump裡面的state的值。同時,為了更快的定位問題,weblogic伺服器會将運作時間超過600秒的執行線程标記為“stuck”狀态,如下所示:

國内首位中間件Oracle ACE:WebLogic執行線程耗盡解決方案
國内首位中間件Oracle ACE:WebLogic執行線程耗盡解決方案
國内首位中間件Oracle ACE:WebLogic執行線程耗盡解決方案
國内首位中間件Oracle ACE:WebLogic執行線程耗盡解決方案
國内首位中間件Oracle ACE:WebLogic執行線程耗盡解決方案
國内首位中間件Oracle ACE:WebLogic執行線程耗盡解決方案
國内首位中間件Oracle ACE:WebLogic執行線程耗盡解決方案

java中線程的狀态

thread dump中,java線程的各種狀态如下:

狀态

說明

new

初始狀态。線程剛剛被建立,并且start()方法還未被調用

runnable

運作狀态。表示線程正在java虛拟機中執行,但是可能正在等待作業系統的其他資源,比如cpu

blocked

阻塞狀态。表示線程正在等待螢幕鎖。表示線程正在等待擷取螢幕鎖,以便進入同步方法或者同步代碼快,也有可能是從wait()方法被喚醒而等待再次進入同步方法或者同步代碼塊

waiting

等待狀态。表示目前線程需要等待其他線程執行一些特殊操作,比如目前線程調用了a.wait()方法,它正在等待其他線程調用a.notify或a.notifyall方法;如果目前線程調用了threada.join(),那麼它在等待threada執行完成

timed_waiting

逾時等待。與waiting的不同在于,該狀态有逾時時間

terminated

終止狀态,表示目前線程已經執行完畢

線程狀态的詳細介紹請參考java源代碼的thread内部類:state。

其中線程狀态中waiting與timed_waiting差別如下:

調用以下三個方法會進入waiting狀态:

object.wait() 不設定逾時時間

thread.join() 不設定逾時時間

locksupport.park() 不設定逾時時間

調用下面的方法會進入timed_waiting狀态:

object.wait(time)

thread.join(time)

thread.sleep(time)

locksupport.parknanos(time)

locksupport.parkuntil(time)

1.6、相關腳本 

收集thread dump的示例腳本如下:

國内首位中間件Oracle ACE:WebLogic執行線程耗盡解決方案

<b>本文來自雲栖社群合作夥伴"dbaplus",原文釋出時間:2016-08-16</b>