*/
publicvoidejbCreate(){
}
/**
*@seejavax.jms.MessageListener#onMessage(javax.jms.Message)
*/
publicvoidonMessage(javax.jms.MessageaMessage){
TextMessagemsg=null;
try{
if(aMessageinstanceofTextMessage){
msg=(TextMessage)aMessage;
StringcrXML=msg.getText();
//System.out.println("MESSAGEBEAN:Message");
//System.out.println(crXML);
ClientReportcr=Serializer.ClientReportXML(crXML);
System.out.println
("Took:"+String.valueOf(cr.getClientElapsedMS())+
"MS.for:"+cr.getType().toString());
}else{
System.out.println("Messageofwrongtype:"+
aMessage.getClass().getName());
}
}catch(JMSExceptione){
System.err.println("MessageBean.onMessage:"+
"JMSException:"+e.toString());
context.setRollbackOnly();
}catch(Throwablete){
System.err.println("MessageBean.onMessage:"+
"Exception:"+te.toString());
}
}
/**
*@seejavax.ejb.MessageDrivenBean#ejbRemove()
*/
publicvoidejbRemove(){
}
}
通常,報告會登記到數據庫中用於在線分析和報告。在本例中,我們將報告打印到控製台以便演示客戶端如何接收它們的過程。方法onMessage()使用Serializer.ClientReportXML()創建來自列隊等待的XML字符串的ClientReport對象。我們在這裏做一下解碼工作以便可以將處理次數保存在事務處理工作流程中。
樣品實現
用來運行樣品應用的所有代碼都可從Resources處下載。我開發代碼時使用的工具是SunONEStudio,EnterpriseEditionUpdate1。這個工具箱包括一個J2EE開發IDE和一個J2EE應用服務,它的Web服務設備采用了嵌入式的JavaWebServiceDeveloperPack1.0_01。Resources處有自由下載URL的信息和到開發者文檔的鏈接。
建立和配置服務器應用
這部分假設你已經了解SunONE應用框架的應用知識。另外,本指示假設你使用微軟的Windows係統。配置的完整源代碼預先已經建立。Web服務客戶端和服務器軟件包已經生成(並為了次數報告的連續化做好修改),但是下麵的描述也包含了關於如何在SunONEIDE之內建立組件的一些背景知識。
要建立和配置服務器應用,首先,在Windows開始菜單中選擇程序,再在程序中選擇SunMicrosystems,然後依次選擇SunONEApplicationServer和StartApplicationServer項。
實用類似的Windows命令可啟動IDE。右擊資源管理器中的"運行"鍵,點擊安裝的服務器,並保證應用服務的運行實例已經設置為默認服務器。
解壓下載的工具包到某個目錄下並右擊IDE資源管理器窗口的文件係統圖標。使用Mount/LocalDirectory對話框,實現兩個不同的安裝命令:
<downloaddirectory>/Metrics/Metrics打開Payload軟件包。
<downloaddirectory>/Metrics/TransactionServer打開服務器EJB、Web模塊、和服務器應用組件。
EJBModule_Xact為應用服務原型,它包括三個商業方法:submitWork()、checkWork()、和getResult()。要創建同一目錄下的TransactionProcessor/Xact_Module可右擊EJB然後依次選擇New、JSP&Servlet、和WebModule命令。創建TransactionService軟件包中的Web模塊可依次選擇New、WebServices、和WebModule向導,然後選擇EJB組件的Java方法作為源程序。右擊WebModule並選擇CreateNewWebService項可自動創建TransactionService/XactServiceGenServer。但是在右擊之前請小心,因為它會關閉添加到類Tie上的Serialize調用。
創建應用程序TransactionServerApp需要依次選擇New、J2EE、和Application命令。右擊空的應用,選擇AddModules項,然後選擇EJBModule_Xact和Xact_ServiceWebModule項就可添加組件到應用程序上。
本部分給出了如何建立代碼組件的一般思想。你需要將這些組件配置到你的應用服務上。在IDE之內,右擊TransactionServerApp即可進行配置。檢查一下應用服務係統控製台以保證它的配置正確。
建立樣品客戶端應用
要建立樣品客戶端應用,請將下列文件係統添加到IDE中:<downloaddirectory>/Metrics/TransactionClient.
該文件係統包含一個應用類和一個Xact軟件包。應用類可模仿客戶端事務的執行,Xact軟件包包含客戶端Web服務處理器。
Xact軟件包可使用SunWeb服務開發者工具包來創建,這個工具包包括在SunONE應用框架內。批文件gen.bat使用wscompile命令創建Xact軟件包。如果你想重建該軟件包的話,你隻需調整環境變量和它使用的config.xml中的URL。但是,如果你這樣做的話,你得重寫添加到Stub類Web方法的代碼行,你要用它來覆蓋原來的代碼行。
我們看看XactClientApp,樣品客戶端應用程序類:
importXact.*;
importjavax.xml.rpc.Stub;
importPayload.*;
publicclassXactClientApp{
/**CreatesanewinstanceofXactClientApp*/
publicXactClientApp(){
}
/**
*@paramargsthecommandlinearguments
*/
publicstaticvoidmain(String[]args){
try{
intcyclesPerXact=1;
intnumberXacts=5;
StringtransactionID="";
StringtransactionType=
String.valueOf(cyclesPerXact)+"submit,check,gets";
Stubstub=createProxy();
XactServiceServantInterfacexact=(XactServiceServantInterface)stub;
CurrentReportcr=newCurrentReport();
for(intx=1;x<=numberXacts;x++){
cr.BeginTransaction();
for(inti=1;i<=cyclesPerXact;i++){
transactionID=xact.submitWork("newtransaction");
System.out.println("Transaction:"+transactionID);
booleanunused=xact.checkWork(transactionID);
Stringignore=xact.getResult(transactionID);
}
cr.CommitTransaction(transactionID,transactionType,"success");
}
}catch(Exceptionex){
ex.printStackTrace();
}
}
privatestaticStubcreateProxy(){
return(Stub)(newXactService_Impl()).getXactServiceServantInterfacePort();
}
}
先看它的內部循環。客戶端應用判斷商業事務的組成。在本例中,它包括三個Web服務調用:針對submitWork()、checkWork()和getResult()的分別調用。客戶端使用beginTransaction()和commitTransaction()定界事務。在該循環的第二個循環中,在CurrentReport.LastReport對象中將出現一個完整的ClientReport。當客戶端調用submitWork()時,Web服務客戶端Stub類中相應方法調用Serializer.attachPendingReportToMessage()將該報告連接到SOAP信息上。
CyclesperXact和numberXacts用於控製每件事務的Web服務調用數和客戶端在運行過程中遞交的事務數。
右擊應用程序圖標XactClientApp;先選擇BuildAll項,接著選擇Execute項。在執行窗口中,你會看到:對於每件事務,應用都報告它收到的事務標誌符。觀察應用服務Windows輸出控製台,你可以看到以下的代碼行:
INFO:CORE3274:successfulserverstartup
INFO:CORE5053:ApplicationonReadycomplete.
INFO:CORE3282:stdout:Exceptionoccurredconnectingtoqueue:javax.naming.Nam
eNotFoundException
INFO:CORE3282:stdout:Exceptionoccurredconnectingtoqueue:javax.naming.Nam
eNotFoundException
INFO:CORE3282:stdout:Exceptionoccurredconnectingtoqueue:javax.naming.Nam
eNotFoundException
INFO:CORE3282:stdout:Exceptionoccurredconnectingtoqueue:javax.naming.Nam
eNotFoundException
我們還沒有安裝應用服務次數排列或者配置應用服務次數讀取器EJB。客戶端產生次數福建,服務器接收它,並試圖將它列隊到一個不存在的隊列中。Serializer類隻是報告錯誤並允許應用程序繼續運行。回想我們的目標之一就是保持商業事物係統的總可靠性。可是我們卻看到即使新的次數組件失敗,關鍵的商業事務仍然可以照常進行。
定義服務器次數隊列
為了定義服務器的次數隊列,我們必須創建一個JavaMessagingService(JMS)隊列以便我們可以異步地傳遞來自於Web服務處理器的次數附件到處理次數的EJB組件中。
SunONE應用服務器有一個嵌入式的SunONE信息隊列(MQ)服務器。你可以三步完成應用服務器內的隊列的定義。首先,定義一個物理目的文件。其次,創建一個關聯的JMS目的文件的源文件。最後,定義QueueConnectionPool,使它能允許應用連接到隊列中並完成操作。
你可以使用ApplicationServerAdministrationConsole來完成這三個步驟。在Windows下,點擊開始菜單,依次選擇程序、Sun微係統、SunONE應用服務、最後選擇StartAdministratorConsole即可。
要創建物理目的文件,你得通過應用服務器來實現,這可以通過依次選擇JMS、Services和PhysicalDestinations來完成。點擊按鈕New就可創建一個新的目的文件。將新文件命名為TestMDBQueue,選擇一個隊列類型,然後點擊OK。
創建隊列的源目的文件也得通過應用服務器。同樣的,選擇JMS,再選DestinationResources。點擊按鈕New,輸入jms/TestMDBQueue作為JNDI(Java命名和目錄接口)名,選擇類型javax.jms.queue並點擊OK。創建了目的文件後,惦記他,然後點擊它的Properties按鈕。輸入唯一的屬性imqDestinationName,並將它賦值為TestMDBQueue。這可以使隊列與我們剛才創建的物理目的文件關聯起來。
最後,我們要創建連接工廠。這也得在應用服務器上進行。選擇JMS,然後選擇ConnectionFactories;點擊New,輸入jms/TestMDBFactory作為JNDI名,選擇類型javax.jms.QueueConnectionFactory,然後點擊OK。
你必須將修改應用到實際的隊列組件上。點擊應用服務器上的ApplyChanges按鈕,在服務器控製台輸出窗口內你將看到創建的新組件:
INFO:JMS5002:Binding[<JMSDestination:jms/TestMDBQueue,javax.jms.Queue,[
imqDestinationName=TestMDBQueue]>=
INFO:JMS5002:Binding[<JMSConnectionFactory:jms/TestMDBFactory,javax.jms.
QueueConnectionFactory,Noproperties>=
建立和配置服務器次數讀取器EJB組件
我們已經創建了一個服務器隊列,現在我們可以配置信息驅動的EJB組件,它可讀取來自隊列的次數附件。首先安裝文件係統<downloaddirectory>/Metrics/MDBTester並點擊TestMDB(EJB)圖標。在它的屬性窗口內,點擊SunONEAS跳格鍵並檢測最後兩個屬性:映射訪問。點擊這兩個屬性並確認他們能夠訪問我們前麵定義的JMS源文件。
右擊EJBModule_TestMDB並選擇Deploy項。在EJB組件配置後,我們在應用服務器控製台的輸出窗口內會看到與下列信息類似的信息:
INFO:MDB00044:Deployingmessage-drivenbean[EJBModule_TestMDB:TestMDB],consu
mingfrom[jms/TestMDBQueue]
INFO:MDB0001:Createmessage-drivenbeanpoolwithmaximumpoolsize[640],bea
nidletimeout[600]seconds
INFO:MDB00022:[EJBModule_TestMDB:TestMDB]:Message-drivenbeanlisteningonJM
Sdestination[TestMDBQueue]
INFO:LDR5010:Allejb(s)of[EJBModule_TestMDB]loadedsuccessfully!
這個EJB組件可放在一個單獨的模塊內因為我們在其他的服務中配置它的機率比事務服務應用中的配置機率還大一些。
運行樣品實現
至此,我們已經配置了次數報告所需的所有基礎設施,我們可以看一些客戶端相應次數的報告。再次執行XactClientApp;這一次,應用服務控製台輸出窗口內將出現下列信息:
INFO:CORE3282:stdout:Took:2613MS.for:1submit,check,gets
INFO:CORE3282:stdout:Took:431MS.for:1submit,check,gets
INFO:CORE3282:stdout:Took:4307MS.for:1submit,check,gets
INFO:CORE3282:stdout:Took:871MS.for:1submit,check,gets
每一次次數讀取器EJB組件都收到一個客戶端報告,它將報告解碼到ClientReport上並報告clientElapsedMS字段。在本例中,IDE和應用服務器都在Compaq公司的Presario膝上型電腦上運行,所以報告的響應次數當然不是典型的應用服務次數。
注意,當客戶端執行五個事務時,實際上隻有四個報告。客戶端應用會話期的最後一個事務不報告因為對於整個報告來說沒有後續的事務可運載報告。
此次實現基本上是一個取樣。它收集了大多數事務--當然足夠測量服務的質量--但是不是全部。要糾正它我們得對客戶端應用做一些調整。提高Payload軟件包可持續會話期間的次數報告,但是這仍然不能保證所有事務都報告。因為我們在次數收集失敗時仍然允許事務繼續,這是一個很重要的目標,整個係統必須總是一個事務取樣器,而不是徹底的記錄器。
改進和後續工作
這個實現可在幾個方麵得到改進,從而為企業提供更多的便利。
你可以擴展ClientReport類,這樣客戶端就可以報告更多關於事務的信息。當分析服務器上的響應次數時,我們知道的關於事務的信息越多,分析就會越好。辨別出哪種事務要占用很長時間,這很重要。由於服務器瓶頸問題,占用很長時間的事務與生俱來的就要複雜一些。減小服務器瓶頸的壓力是原則性的目標。改進ClientReport最好的方法是添加(attribute,value)字符串排列,該排列允許客戶端報告事務的二進製特征。
次數收集結構也有助於企業服務管理的其它方麵。當服務器在域中有上千個或者上萬個客戶端的話,保證服務器軟件升級後仍與現有的客戶端庫兼容,這很重要。但是哪種軟件版本是客戶端運行的呢?這常常難以確定,但是如果ClientReport類可以使用客戶端軟件版本域擴展,也可使用客戶端操作係統版本擴展,簡單的次數數據庫查詢就會提供該信息。
你可以改進Payload軟件包來報告客戶端軟件錯誤。客戶端異常處理可保存產生失敗的上下文的細節,這樣當應用程序重啟時Payload軟件包可以上傳該信息。這突出了主要潛在問題的一個方麵:警報。次數讀取器EJB組件在收到客戶端軟件錯誤報告時,就可以開始它的商業工作流程處理。它可以產生一個SNMP(簡單網絡管理協議)陷阱或者發送email,允許客戶服務人員啟動一個調用到擅長解決問題的用戶那裏去。
接收精確的客戶端響應次數
在本文中,我展示了如何將事務響應次數記錄層壓到現有的J2EE服務應用上。該方法可用於測量客戶端應用方麵的精確的響應次數。這個實現是輕便的。客戶端和服務器之間不需要新的網絡通信。次數有效載荷為低優先級的登記列隊等待,所以預訂服務器資源來處理應用程序。