門(mén)戶中的資源掛起線程應(yīng)急解決方案
門(mén)戶中的資源掛起線程應(yīng)急解決方案時(shí)間:2006-05-26 作者:Michael Poulin 瀏覽次數(shù): 124 本文關(guān)鍵字:WebLogic Portal,?thread hanging,?Workaround,?線程掛起,?應(yīng)急方案 |
|

業(yè)務(wù)任務(wù)
您的門(mén)戶出現(xiàn)用戶請(qǐng)求在資源中掛起情況的頻率是多高?我希望這種情況不經(jīng)常發(fā)生。然而,如果出現(xiàn)了這種情況,而且資源不斷掛起用戶請(qǐng)求,則門(mén)戶會(huì)面臨耗盡所有已配置的并發(fā)用戶請(qǐng)求并最終崩潰的致命風(fēng)險(xiǎn)。這將是一場(chǎng)災(zāi)難。我碰到過(guò)幾次這樣的情況,并決定保護(hù)我的門(mén)戶不再受類(lèi)似情況的影響。
我們需要讓門(mén)戶包含幾個(gè)具有登錄控件(通過(guò)用于每個(gè)Portlet的備份文件提供)的Portlet。對(duì)于每個(gè)請(qǐng)求,創(chuàng)建一個(gè)備份文件,備份文件在用戶請(qǐng)求方面是線程安全的。在登錄控件中,備份文件的init()方法(或preRender()方法)調(diào)用獨(dú)立的安全服務(wù)(資源)API以獲得資源訪問(wèn)授權(quán)。對(duì)于業(yè)務(wù)處理,Portlet也通過(guò)其他API調(diào)用將用戶請(qǐng)求委托到業(yè)務(wù)層。一切都運(yùn)行正常,直到一個(gè)對(duì)資源的調(diào)用未返回到Portlet,即,由于某種原因,它在某處掛起了。以下是一個(gè)具體示例。
我們假定WebLogic Portal使用EJB作為業(yè)務(wù)層和/或安全服務(wù)中的資源。此EJB操作其他資源,并通過(guò)使用JMS發(fā)送消息的方式報(bào)告處理狀態(tài)。此EJB與其他應(yīng)用程序一起部署在集群中。門(mén)戶部署在另一個(gè)物理機(jī)器上。如果共同部署的一個(gè)應(yīng)用程序引發(fā)了內(nèi)存錯(cuò)誤,則整個(gè)集群(包括EJB)都會(huì)掛起,即它不返回請(qǐng)求也不拋出異常。事實(shí)上,討論如此顯著的失效是沒(méi)有必要的:從門(mén)戶的角度來(lái)說(shuō),“掛起”模式僅是門(mén)戶的動(dòng)態(tài)并發(fā)生命周期中的一種返回得過(guò)慢、延遲過(guò)久以至于不能接受的響應(yīng)。例如,延遲可能由于服務(wù)器過(guò)載或數(shù)據(jù)庫(kù)出現(xiàn)問(wèn)題引起,但這是不相干的——備份文件中的線程運(yùn)行時(shí)間超出了正常門(mén)戶工作的允許范圍,達(dá)到了門(mén)戶中的“最大并發(fā)用戶數(shù)”。此門(mén)戶完全停止接受用戶請(qǐng)求——這就成了問(wèn)題。
解決方案設(shè)計(jì)
我首先想到的是,在Portlet用于訪問(wèn)其資源的RMI客戶端(即EJB客戶端)上設(shè)置超時(shí)(遠(yuǎn)程-客戶端-超時(shí))。然而,關(guān)于使用RMI超時(shí)的WebLogic指導(dǎo)原則列出了關(guān)于此類(lèi)超時(shí)的幾條限制,其中包括“在調(diào)用中不涉及JMS資源。”這就是說(shuō),不能對(duì)EJB資源使用超時(shí)。我提及這種情況只是為了說(shuō)明存在門(mén)戶可能未被保護(hù)以不受掛起的資源線程影響的情況。即使沒(méi)有關(guān)于超時(shí)的限制,如果請(qǐng)求掛起的速度快于超時(shí)釋放相關(guān)線程的速度,問(wèn)題就依然存在。
我想介紹一種針對(duì)此問(wèn)題的可能解決方案。此解決方案在下面的條件下有效:門(mén)戶具有一些獨(dú)立于可能會(huì)掛起的資源的內(nèi)容或功能。就是說(shuō),門(mén)戶可以運(yùn)行部分功能。
此解決方案包括3個(gè)組件:監(jiān)控、決策規(guī)則和規(guī)則實(shí)施方法。此解決方案的原理很簡(jiǎn)單:門(mén)戶監(jiān)控運(yùn)行中的資源調(diào)用,從而監(jiān)控被調(diào)用的資源線程,對(duì)運(yùn)行過(guò)久的資源線程的數(shù)量進(jìn)行計(jì)數(shù)(riskCounterValue),然后應(yīng)用決策規(guī)則,如“如果riskCounterValue達(dá)到或超出預(yù)定義的閾值(riskThreshold),則所有傳入的對(duì)此資源的調(diào)用均被拒絕,直到riskCounterValue小于riskThreshold。”使用此規(guī)則可以限制可能“掛起”的資源線程數(shù)量,而且可能使用簡(jiǎn)化功能處理用戶請(qǐng)求。例如,如果門(mén)戶包含4個(gè)Portlet,用于一個(gè)Portlet的某些資源線程被認(rèn)為“存在掛起的風(fēng)險(xiǎn)”,則門(mén)戶可以跳過(guò)存在風(fēng)險(xiǎn)的Portlet而僅對(duì)用戶顯示3個(gè)Portlet。
規(guī)則實(shí)施方法的實(shí)現(xiàn)非常重要。如果此規(guī)則在每個(gè)調(diào)用的范圍內(nèi)執(zhí)行,我們可以預(yù)見(jiàn)性能會(huì)降低,但是可以輕松地控制可能“掛起”的資源線程。如果此規(guī)則在調(diào)用以外執(zhí)行,我們可以保持性能,但是對(duì)此類(lèi)控制的調(diào)整是需要技巧的。我們將詳細(xì)討論后一種情況。圖1的圖描述了這種情況。
如圖所示,在第一步中,門(mén)戶初始化一個(gè)Helper對(duì)象,而此Helper對(duì)象則初始化一個(gè)CallRegistry對(duì)象。后者可作為java.util.HashMap實(shí)現(xiàn),并用于注冊(cè)所有對(duì)資源API的調(diào)用。然后Helper啟動(dòng)一個(gè)watchdog線程。例如,如果使用Struts,則此線程就在模型中啟動(dòng)。watchdog線程定期檢查CallRegistry中的記錄,對(duì)運(yùn)行時(shí)間過(guò)長(zhǎng)的調(diào)用數(shù)量進(jìn)行計(jì)數(shù),并將其設(shè)置為Helper中的riskCounterValue變量。
假定我們大概知道API調(diào)用的正常執(zhí)行時(shí)間。該值(最長(zhǎng)持續(xù)時(shí)間)可以用于所有的API,或者每個(gè)API可以具有其單獨(dú)的執(zhí)行時(shí)間。因此,當(dāng)調(diào)用一個(gè)API方法時(shí),我們可以計(jì)算此API在正常情況下預(yù)期完成的時(shí)間,例如:
java.lang.System.currentTimeMillis() long apiExecutionTime = ...;// property long timeToComplete = java.lang.System.currentTimeMillis() + apiExecutionTim
當(dāng)調(diào)用Helper的方法時(shí),它將一條新記錄添加進(jìn)CallRegistry。此記錄包括一個(gè)惟一的調(diào)用ID(用作java.util.HashMap中的鍵)和用于API的預(yù)期完成時(shí)間(timeToComplete)(用作java.util.HashMap中的值)。如果此方法成功完成,它會(huì)從CallRegistry移除其記錄。
讓我們來(lái)看一下用戶請(qǐng)求是如何處理的。接到用戶請(qǐng)求后,Portlet的備份文件將其委托給Helper API方法(后者調(diào)用資源API)。首先,此Helper API方法檢查其是否可以執(zhí)行。如果接到請(qǐng)求的時(shí)候尚未達(dá)到riskThreshold,則此Helper API方法繼續(xù)運(yùn)行。否則,它會(huì)拋出一個(gè)異常,門(mén)戶會(huì)繼續(xù)下一項(xiàng)功能或下一個(gè)API調(diào)用。
僅在運(yùn)行時(shí)間過(guò)長(zhǎng)的資源線程數(shù)量(riskCounterValue)小于riskThreshold的情況下才可以賦予執(zhí)行的權(quán)限。通過(guò)配置屬性設(shè)置riskThreshold。例如,如果將并發(fā)用戶請(qǐng)求最大值配置為25,則riskThreshold可以設(shè)置為10。這就是說(shuō),門(mén)戶處理并發(fā)用戶請(qǐng)求的能力僅存在一半風(fēng)險(xiǎn),它在資源線程開(kāi)始掛起的情況下仍然可以運(yùn)行。
請(qǐng)注意我們不對(duì)運(yùn)行時(shí)間過(guò)長(zhǎng)的API調(diào)用進(jìn)行任何操作。它們中的一些最終可以成功完成,Helper API方法會(huì)將其記錄從CallRegistry移除,即下一次計(jì)數(shù)可能會(huì)低于riskThreshold,下一次針對(duì)資源的用戶請(qǐng)求可能不會(huì)被拒絕(通過(guò)拋出異常的方式)。
門(mén)戶無(wú)法知道網(wǎng)絡(luò)中是否存在意外延遲或者資源線程是否確實(shí)掛起。因此,推薦在幾個(gè)順序控制周期中達(dá)到或超出riskThreshold時(shí)給操作團(tuán)隊(duì)發(fā)送一個(gè)通知(例如,通過(guò)電子郵件)。收到的通知允許操作團(tuán)隊(duì)迅速分析日志,及時(shí)找到并解決運(yùn)行時(shí)間過(guò)長(zhǎng)的調(diào)用的原因。
分析和調(diào)整
對(duì)“掛起”的資源線程的控制具有很大的動(dòng)態(tài)性,要對(duì)其進(jìn)行調(diào)整并不是一件簡(jiǎn)單的事。其效果是基于對(duì)以下3個(gè)參數(shù)的權(quán)衡:
- 用戶請(qǐng)求之間的平均時(shí)間(TUR)與watchdog線程控制周期(風(fēng)險(xiǎn)控制周期)之間的時(shí)間(TRC)的比率:R = TUR / TRC
- 用于特定資源的風(fēng)險(xiǎn)閥值(riskThreshold)
- 資源API調(diào)用的預(yù)期執(zhí)行時(shí)間
對(duì)控件的研究和測(cè)試得出的結(jié)論是,參數(shù)調(diào)整取決于特定的門(mén)戶實(shí)現(xiàn),但具有共同的趨勢(shì)。圖2中的圖表展示了用于調(diào)整的準(zhǔn)則。在測(cè)試中,比率被設(shè)為R = 95%,TUR為95[ms],TRC被設(shè)為100[ms]。通常,可靠的比率是90%或更高。
此圖表顯示“掛起”的API調(diào)用數(shù)(在控件中計(jì)數(shù))是如何取決于調(diào)用執(zhí)行時(shí)間的。圖表中的點(diǎn)代表風(fēng)險(xiǎn)控制周期之間掛起的用戶請(qǐng)求的最大數(shù)量,即在針對(duì)給定調(diào)用執(zhí)行時(shí)間而進(jìn)行的一系列測(cè)試中的riskCounterValue最大值。請(qǐng)記住,在實(shí)施決策規(guī)則時(shí),一些用戶請(qǐng)求被拒絕,而“掛起”的資源線程數(shù)量不會(huì)增加。
圖2中的水平紅線標(biāo)記門(mén)戶中所允許的最大并發(fā)用戶數(shù)量。控件的目的是將最大riskCounterValue嚴(yán)格保持在紅線以下。圖表中的點(diǎn)越接近紅線,就越可能達(dá)到或超出riskThreshold。
我們可以看到,控制的行為不明顯。對(duì)于某些調(diào)用執(zhí)行時(shí)間值(從3250ms到1500ms),控件生成用戶請(qǐng)求,“掛起”的資源線程數(shù)量接近并超出門(mén)戶允許的并發(fā)用戶最大值。在此間隔期間,控制在給定條件下是無(wú)效的。同時(shí),控制在從100ms到1000ms和從3500ms到4000ms的2個(gè)間隔中是有效的:具有特定riskThreshold的決策規(guī)則可靠地保護(hù)門(mén)戶不受“掛起”的API調(diào)用的影響,并保留足夠的并發(fā)請(qǐng)求線程以服務(wù)其他用戶請(qǐng)求。
此圖表還顯示較小的riskThreshold可提供較好的保護(hù)。但是,如果將一個(gè)資源的riskThreshold設(shè)置得過(guò)低,資源可能僅僅由于網(wǎng)絡(luò)延遲的輕微波動(dòng)就在大多數(shù)用戶會(huì)話中不可用。這是另一個(gè)主題了:平衡和調(diào)整。
結(jié)束語(yǔ)
這套關(guān)于“掛起”的資源調(diào)用的運(yùn)行時(shí)控制的推薦解決方案允許門(mén)戶隔離有問(wèn)題的資源,并使用余下的資源繼續(xù)運(yùn)行,從而最大程度地減小對(duì)性能的影響。此解決方案的效果取決于以下幾個(gè)調(diào)整參數(shù):請(qǐng)求頻率和風(fēng)險(xiǎn)控制周期頻率的比率、風(fēng)險(xiǎn)閥值的值和預(yù)期的調(diào)用執(zhí)行時(shí)間。
這種情況下的調(diào)整不是一件容易的事——它需要密集的測(cè)試。此外,本文中給出的數(shù)字是特定于我的測(cè)試門(mén)戶的,即使您發(fā)現(xiàn)了相關(guān)性,在您的門(mén)戶上進(jìn)行的測(cè)試中使用的應(yīng)該是其他值。另一方面,如果某種程度的性能降低是可以接受的,則推薦在每個(gè)API調(diào)用的范圍內(nèi)執(zhí)行風(fēng)險(xiǎn)控制周期,以顯著簡(jiǎn)化解決方案參數(shù)的調(diào)整。
參考資料
- WebLogic RMI特性和指導(dǎo)原則:關(guān)于使用RMI超時(shí)的指導(dǎo)原則http://e-docs.bea.com/wls/docs81/rmi/rmi_api.html
- Nyberg, G.、Patrick, R.、Bauerschmidt, P.、McDaniel, J.以及Mukherjee, R.所著的“Mastering BEA WebLogic Server: Best Practices for Building and Deploying J2EE Applications”,Wiley E-Book,2004年3月出版。ISBN: 0-471-48090-8。
原文出處: http://wldj.sys-con.com/read/185309.htm

?作者簡(jiǎn)介 | |
Michael Poulin 是一位技術(shù)架構(gòu)師,現(xiàn)供職于華爾街一家大型公司。他是Sun認(rèn)證的Java技術(shù)架構(gòu)師。過(guò)去數(shù)年來(lái),他專(zhuān)攻分布式計(jì)算、應(yīng)用程序安全性和SOA。 |
posted on 2006-06-11 14:54 【Xine】中文站 閱讀(522) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): Bea Weblogic