背景介紹
隨著基於 Java EE 多層架構的應用在企業級范圍內的廣泛部署,來源於此類架構的性能問題日益引起人們的關注。架構的多層性使得性能問題出現時,需要花費大量的時間和精力逐步排查,以定位性能瓶頸,這往往是一個費力不討好的過程,更為重要的是,面對關鍵業務系統,性能問題對業務運營的沖擊是直接而明顯的。
WAS 是目前業界使用最為廣泛的應用服務器之一,為金融、電信、制造等行業的關鍵業務系統提供基礎支撐,Tivoli 是出眾的 IT 基礎架構及應用管理軟件,如何將 IT 管理軟件有效的應用到基礎架構軟件中,提高日常管理工作的有效性和精確性,ITCAM for WebSphere 或許能給出部分答案。
ITCAM 簡單介紹
ITCAM 即 IBM Tivoli Composite Application Management,是 IBM 五大品牌軟件系列中 Tivoli 的一個組成部分,它主要專注於多層架構下的應用的管理,術語 Composite,即合成的,意指應用是多層合成的。
ITCAM 本身由一系列產品組成,有專門針對 SOA 管理的 ITCAM for SOA,也有專門針對其他 J2EE 應用服務器管理的 ITCAM for J2EE,而 ITCAM for WebSphere 則是作為單獨的一個產品系列存在。
ITCAM for WebSphere 在功能上提供了性能分析、線程死鎖分析、內存洩露分析等一系列高級的功能,通過使用一個單一的管理控制台即可對企業范圍內的 WAS 進行高級診斷。
ITCAM 自身的架構分為兩個層次:數據收集層和管理服務層,如圖 1:
圖 1. ITCAM 的架構
數據收集層的主要部件就是 Data Collector,即數據收集器,它位於被管理的服務器上,主要工作是收集必需的采樣數據,這些數據隨後被發送到 ITCAM 的管理服務層。
管理服務層的關鍵部件是 Managing Server,即管理服務器,它包含了若干個服務,這些服務接收發送自數據收集器的數據,經過統計、分析和整理,向使用者提供性能分析報告。
管理服務器後端是一個數據庫,用於存放歷史數據。
樣本應用 Plants by WebSphere 簡單介紹
這是 WAS V6.1 自帶的一個樣本應用,該應用是一個網上店面,專門銷售植物和園藝工具。
登錄網上店面後,簡單的做一些查詢,購買商品操作,然後准備提交訂單,下圖 2 是提交訂單前的確認信息的界面:
圖 2. 提交訂單前的確認信息
在使用中發現,提交訂單的操作異常的消耗時間,一般需要經歷 15 到 20 秒不等的時間才能出現如圖 3 提交成功的頁面:
圖 3. 提交成功後的頁面
為了徹底了解提交訂單後是哪個環節導致了耗時的操作,我們將借助於 ITCAM for WebSphere 這一強大的管理工具進行問題的診斷定位。
ITCAM for WebSphere 的配置
ITCAM for WebSphere 的主要配置工作都是針對數據收集器的,這些工作有的可在 ITCAM for WebSphere 的控制台完成,有的則需要在數據收集器端直接修改配置文件。其配置的過程如下:
配置類過濾配置
類過濾配置簡稱配置,配置是給數據收集器使用的,用來指導數據收集器在工作時哪些類需要進行數據收集,而哪些類不必進行數據收集。ITCAM for WebSphere 中可以存在多個不同的配置,這些配置保存在配置庫當中。
登錄 ITCAM for WebSphere 管理控制台,選擇菜單管理 > Server Management > Data Collector Configuration(圖 4),以進入 CONFIGURED DATA COLLECTOR OVERVIEW 界面(圖 5)。
圖 4. Data Collector Configuration 菜單項
在 CONFIGURED DATA COLLECTOR OVERVIEW 界面(圖 5)中點擊 Configuration Library 鏈接,即配置庫。
圖 5. CONFIGURED DATA COLLECTOR OVERVIEW 界面
來到 DATA COLLECTOR CONFIGURATION LIST 界面,屏幕右側即為配置列表,可以看到內置了多個缺省的配置,選擇名為 J2EE Default 的配置(圖 6),點擊其對應的 Duplicate 按鈕,我們要在此配置的基礎上復制一份,然後略作修改。
圖 6. 選擇復制 J2EE Default 配置
在 DUPLICATE CONFIGURATION 界面(圖 7)中,將新配置的名稱命名為 WebSphere,然後點擊 Save 按鈕。
圖 7. 命名新配置為 WebSphere
回到更新的 DATA COLLECTOR CONFIGURATION LIST 界面,新增加的 WebSphere 配置已經在列表當中(圖 8),點擊其對應的 Modify 按鈕,進行定制。
圖 8. 選擇 WebSphere 配置進行定制
在 MODIFY CONFIGURATION 界面(圖 9)中對 WebSphere 配置的類過濾進行定義。定義由兩部分組成,Exclude和 Exclude Override。
Exclude 中定義了那些不需要進行數據收集的類;而Exclude Override 中則定義了需要進行數據收集的類。Exclude 和 Exclude Override 中的類名都可以使用通配符來表示。
為了便於理解,我們通過一個簡單的例子加以說明。請考慮以下情況,我們在 Exclude 中使用了通配符 com.ibm.*,則所有 com.ibm 包中的類都被排除在外,但我們同時又希望可以有少量 com.ibm 包中的類不被排除在外,如 com.ibm.websphere.samples,這個時候只需要在 Exclude Override 中加入 com.ibm.websphere.samples.* 就可以了。
針對本例中的情況,在 Exclude(Classname) 編輯框中追加 ibm.console.* ,以避免對 WAS 控制台所使用的類進行數據收集;在 Exclude Override (Classname) 編輯框中追加 com.ibm.websphere.samples.*,因為在 Exclude 中有 com.ibm.*,為了能對 Plants by Websphere 中所使用到的類進行數據收集,所以要在 Exclude Override 中又將 Plants by Websphere 使用到的類挑出來。
完成後點擊 Save 按鈕。
圖 9. 對 WebSphere 配置進行定制
由 Exclude 和 Exclude Override 組合而成的類過濾設置,其粒度與將來產生的性能報告的詳細程度息息相關:過濾設置得太細,很多類方法的調用可能會漏掉,這當中就可能包括那些耗時的方法調用;反之,又會將那些無關緊要的方法調用也統計出來,並加重了服務器的負擔
一般地,基礎軟件類都是在 Exclude 中的,比如JDK核心類、J2EE核心類、WebSphere核心類等,而業務系統中所使用到自開發類則不應該處於 Exclude 列表中。
將類過濾配置應用到數據收集器
數據收集器在運行期間能正常收集數據,必須有一個具體的配置應用到數據收集器上。一個數據收集器,如果沒有應用配置,我們稱之為未配置的數據收集器,反之,則稱為配置的數據收集器。
在 CONFIGURED DATA COLLECTOR OVERVIEW 界面(圖 10)中點擊 Unconfigurated Data Collector 鏈接,即未配置的數據收集器。
圖 10. CONFIGURED DATA COLLECTOR OVERVIEW 界面
在 UNCONFIGURED DATA COLLECTOR OVERVIEW 界面中,鼠標勾選相應的數據收集器(圖 11),並在 Apply a Configuration 下拉列表中選擇 WebSphere 配置,然後點擊 Apply 按鈕。
圖 11. 將 WebSphere 配置應用到數據收集器
頁面自動跳轉到 CONFIGURED DATA COLLECTOR OVERVIEW 界面,可以看到之前未配置的數據收集器現在已經變為配置的數據收集器(圖 12)。
圖 12. 當前配置的數據收集器
設置數據收集器監控級和采樣頻率
在 ITCAM for WebSphere 管理控制台,選擇菜單管理 > Managing Server > System Properties(圖 13),進入 SYSTEM PROPERTIES 界面。
圖 13. System Properties 菜單項
在 SYSTEM PROPERTIES 界面中,設置對所有的數據收集器均有效。
監控級別分為三級:
表 1. 數據收集器監控級別列表
針對每個級別,缺省的采樣頻率都是 2%,這是相當保守的設置,目的是使得對目標服務器的影響盡可能降到最低,這對於生產環境是合適的。
在測試環境中的取樣,可以采取比較激進的設置,如 100% 的采樣,這裡我們將使用最高監控級 L3,並且設為 100% 采樣,如圖 14 所示:
圖 14. 測試環境中的監控級和采樣設定
打開數據收集器對方法調用的時間統計
缺省的,在 L3 監控級別,數據收集器只會對 EJB, JNDI, RMI, Servlet 等類型的調用作時間統計,為了獲得更加詳細的統計數據,在某些情況下需要對所有的方法調用進行時間統計,這需要手工修改數據收集器的配置文件。
打開 DC_HOME/runtime/app_server_version.node_name.server_name/custom/toolkit_custom.properties 文件,將
com.ibm.tivoli.itcam.toolkit.ai.methodentryexittrace=false
中的 false 改為 true。這將打開 L3 監控級別下對方法調用的時間統計。
將
#am.camtoolkit.gpe.customxml.L3=C:/IBM/itcam/WEBSPH~1/DC/itcamdc/etc/method_entry_exit.xml
前的 # 號去除,表示對所有的方法調用作時間統計。
重啟數據收集器所在的 WAS
在本章節中,我們分別通過 ITCAM for WebSphere 的管理控制台和修改數據收集器物理配置文件的方式,對 ITCAM for WebSphere 的工作環境做了適當的配置。
為使配置生效,需要重新啟動數據收集器所在的 WAS 進程。
使用 ITCAM for WebSphere 進行分析
執行兩次Plants by WebSphere 網上店面中的采購流程,該流程包含了登錄、查詢、提交訂單等操作,目的是使得數據收集器能完成采樣的任務,這些采樣的數據是我們進行統計分析的依據。
產生性能分析報告
在 ITCAM for WebSphere 管理控制台,選擇菜單性能分析 > Create Application Reports > Request/Transaction,如圖 15 所示:
圖 15. Request/Transaction 菜單項
在 SERVER SELECTION 界面(圖 16)中的 Server 下拉列表中,選擇對應數據收集器所在的 WAS 實例,然後點擊 Next 按鈕。
圖 16. 選擇 WAS 實例
在 REPORT FILTERING OPTIONS 界面(圖 17)中的 Metric 下拉列表中,選擇 Response Time 作為度量,然後點擊 Next 按鈕。
圖 17. 選擇 Response Time 作為度量標准
在 DATE RANGE SETTINGS 界面(圖 18)的 Preset 下拉列表中,選擇時間段為 Last 60 Minutes,然後點擊 View Report 按鈕。
圖 18. 選擇時間段
察看性能分析報告
分析報告產生後,頁面自動跳轉到 TREND REPORT 界面(圖 19),我們可以看到在 Last 60 Minutes 時間段,所有請求的平均響應時間是 1632 毫秒。因為在產生報告的設置過程中,選擇的度量是響應時間,所以這裡的給出的統計就是以響應時間計。
在 TREND REPORT 界面(圖 19)中,點擊紅色柱狀圖,將進入 URL 請求分布圖。
圖 19. 選定時間段內所有請求的平均響應時間
來到 DECOMPOSTION REPORT 界面(圖 20),這裡展示的是 URL 請求的分布情況,處理提交訂單請求的 URL 是 /PlantsByWebSphere/servlet/ShoppingServlet,點擊以獲得進一步詳細的統計。
圖 20. URL 請求分布圖
在URL 請求統計的 Detail 屬性頁(圖 21),仔細觀察該 URL 請求的詳細采樣統計分析,發現有 2 次請求的響應時間異常的高,分別是 29 秒和 21 秒!
點擊兩個當中的任何一個感興趣的采樣進入。
圖 21. 異常高的響應時間
來到 TRACE REPORT 界面,選擇 Flow View 屬性頁,這將把該次請求的層層調用堆棧展示出來,如圖 22 所示:
圖 22. 請求的調用堆棧
我們需要觀察的是 ΔElapsed Time 時間,確認在哪個方法調用中,所消耗的時間最長。依次下翻,如圖 23 所示,可以發現一個名為 MailerBean 的 EJB 當中的 createAndSendMail 方法占用時間長達 29031 毫秒,基本上為該次請求響應時間的 99% 以上,因此可以確認問題出在這裡!
圖 23. 耗時的createAndSendMail調用
在大部分應用中,通常與數據庫的交互是性能瓶頸所在,而在該例中,一個發送郵件的操作占用如此之多的時間,實屬不太正常。
通過 ITCAM for WebSphere 產生的性能分析報告,我們很快的定位出了導致了性能問題的環節。
分析 MailerBean 代碼
在 MailerBean.java 中,我們定位到 createAndSendMail 方法,發現在 JNDI 代碼調用之後,到 createAndSendMail 方法結束之前,有若干個方法調用:
清單 1. createAndSendMail 代碼
public void createAndSendMail(CustomerInfo customerInfo, String orderKey)
throws MailerAppException {
try {
EMailMessage eMessage =
new EMailMessage(createSubjectLine(orderKey),
createMessage(orderKey),customerInfo.getCustomerID());
Util.debug("Sending message" +
"\nTo: " + eMessage.getEmailReceiver() +
"\nSubject: " + eMessage.getSubject() +
"\nContents: " + eMessage.getHtmlContents());
Session session =
(Session) Util.getInitialContext().lookup(MAIL_SESSION);
MimeMessage msg = new MimeMessage(session);
msg.setFrom();
msg.setRecipients(Message.RecipientType.TO,
InternetAddress.parse(eMessage.getEmailReceiver(), false));
msg.setSubject(eMessage.getSubject());
MimeBodyPart mbp = new MimeBodyPart();
mbp.setText(eMessage.getHtmlContents(), "us-ascii");
msg.setHeader("X-Mailer", "JavaMailer");
Multipart mp = new MimeMultipart();
mp.addBodyPart(mbp);
msg.setContent(mp);
msg.setSentDate(new Date());
Transport.send(msg);
Util.debug("\nMail sent successfully.");
}
catch (javax.naming.NamingException e) {
Util.debug("javax.naming.NamingException, Has mail session been created?");
}
catch (Exception e) {
Util.debug("createAndSendMail exception : " + e);
throw new MailerAppException("Failure while sending mail");
}
}
而這些方法由於屬於 javax.mail 包的類所提供的方法,而 javax 包在類過濾配置中被排除在外,即任何屬於 javax 包的類提供的方法,都不會被統計分析,而這些遺漏的方法則恰恰可能是引起性能問題的方法!
從這裡我們可以看到,類過濾配置中,對 Exclude 和 Exclude Override 的定義將直接影響性能分析報告的詳細度。
在活動的請求視圖中進一步分析
重新對 Plants by WebSphere 網上店面中的采購流程執行一次,在提交訂單尚未返回應答之前,在 ITCAM for WebSphere 管理控制台,選擇菜單問題確定 > Server Activity Display(圖 24)。
圖 24. Server Activity Display 菜單項
在SERVER ACTIVITY DISPLAY 界面(圖 25)中的 Server 下拉列表中,選擇對應數據收集器所在的 WAS 實例。
圖 25. 選擇 WAS 實例
頁面自動跳轉到 SERVER ACTIVITY DISPLAY 界面中的 Active Requests 屬性頁,這裡可以看到正在處理中的提交訂單的請求(圖 26),點擊 ACTIVE REQUESTS 表格中的 /PlantsByWebSphere/servlet/ShoppingServlet 鏈接以獲取進一步詳細的數據。
圖 26. 活動請求的列表
在隨後出現的界面中,點擊 Stack Trace 鏈接,這將把當前請求的調用堆棧打印出來,圖 27 展示了這個調用堆棧的頂部。
可以發現,在 MailerBean 這個 EJB 的 createAndSendMail 方法中,所包含的後續方法調用,屬於一系列的 javax 包中的接口和對應的實現類,這與我們在 MailerBean.java 代碼中分析的結果是一致的。
圖 27. 活動請求的調用堆棧頂部
將頁面繼續往下翻,展示調用堆棧的中部,讓 createAndSendMail 方法出現在頁面中能觀察到的位置(圖 28),然後以 createAndSendMail 方法為起始,自下而上觀察。
圖 28. 活動請求的調用堆棧中部
上圖所揭示的問題根源就相當直觀了,由於 java.net.SocketInputStream 類當中 socketRead 這個阻塞方法的調用掛起,直接導致 MailerBean 的 createAndSendMail 方法占用了大量的時間這一表面現象。
結論
ITCAM for WebSphere 有效的幫助我們定位出了導致性能問題的環節,接下來的工作就是有的放矢,對相應環節進行調整優化,比如操作系統、網絡、WAS 本身的配置、代碼等。
在很多情況下,響應時間超長或線程掛起,通常都是因為某些關鍵資源無法獲取,比如請求數據庫連接、等待 SQL 返回結果、等待網絡套接字可讀等。
在本例中,影響性能的環節似乎與網絡通訊相關。我們把重點放在網絡配置的檢查上,發現 Windows 機器在對 WAS 中缺省的郵件傳輸主機 yourcompany.ComOrNet 進行名字解析時,內部域名服務器意外的將這個本不存在的郵件傳輸主機解析為 IP 地址 59.37.71.87,盡管該地址的 SMTP 端口處於監聽狀態,但對於任何未經授權的連接都不予以響應。而 javax.mail.Transport 接口的 send 方法在執行後,會一直等待響應直到連接被重置,這個過程耗時 15 ~ 25 秒不等,這就是導致整個提交訂單的操作消耗大量時間的直接原因。