英文來自:Top 10 Causes of Java EE Enterprise Performance Problems,翻譯:CSDN
本文作者Pierre-Hugues Charbonneau是加拿大一名有10多年經驗的高階系統架構師,他的主要專業領域是Java EE、中介軟體和JVM技術。他在效能優化和提升方面也有很深刻的見解,下面他將和大家分享一下常見的10個影響Java EE效能問題。
0.缺乏正確的容量規劃
容量規劃是一個全面的和發展的過程標準,預測當前和未來的IT環境容量需求。制定合理的容量規劃不僅會確保和跟蹤當前IT生產能力和穩定性,同時也會確保新專案以最小的風險部署到現有的生產環境中。硬體、中介軟體、JVM、調整等在專案部署之前就應該準備好。
1.Java EE中介軟體環境規範不足
“沒有規矩,不成方圓”。第二個比較普遍的原因是Java EE中介軟體或者基礎架構不規範。在專案初始,新平臺上面沒有制定合理的規範,導致系統穩定性差。這會增加客戶成本,所以花時間去制定合理的Java EE中介軟體環境規範是必須的。這項工作應與初始容量規劃迭代相結合。
2.Java虛擬機器垃圾回收過度
各位對“java.lang.OutOfMemoryError”這個錯誤資訊是不是很熟悉呢?由於JVM的記憶體空間過度消耗(Java堆、本機堆等)而丟擲的異常。
垃圾收集問題並不一定會表現為一個OOM條件,過度的垃圾收集可以理解成是JVM GC執行緒在短時間裡進行輕微或超量收集集合資料而導致的JVM暫停時間很長和效能下降。可能有以下幾個原因:
1.與JVM的負載量和應用程式記憶體佔用量相比,Java堆可能選擇的太小。
2.JVM GC策略使用不合理。
3.應用程式靜態或動態記憶體佔用量太大,不適合在32位JVM上使用。
4.JVM OldGen隨著時間推移,洩漏越來越嚴重,而GC在幾個小時或者幾天後才發現。
5.JVM PermGen空間(只有HotSpot VM)或本機堆隨著時間推移會洩露是一個非常普遍的問題;OOM的錯誤往往是觀察一段時間後,應用程式進行動態調動。
6.YoungGen和OldGen的比例空間與你的應用程式不匹配。
7.Java堆在32位的VM上太大,導致本機堆溢位,具體可以表現為OOM試著去連結一個新的Java EE應用程式、建立一個新的Java執行緒或者需要計算本地記憶體分配任務。
建議:
1.觀察和深入理解JVM垃圾回收。啟動GC,根據健康合理的評估來提供所有的資料。
2.記住,GC方面的相關問題不會在開發中或者功能測試時發現,它需要在多使用者高負載的測試環境下發現。
3.與外部系統整合過多或過少
導致Java EE效能差的第四個原因是高分散式系統,典型案例是電信IT環境。在這個環境中,一箇中介軟體領域(例如,服務匯流排)很少會做所有的工作,而僅僅是把一些業務“委託”給其他部分,例如產品質量,客戶資料和訂單管理,到其他Java EE中介軟體平臺或遺留系統中,如支援各種不同的負載型別和通訊協議的大型機。
這樣的外部系統呼叫意味著客戶端的Java EE應用程式觸發建立或重用套接字連結從外部系統中讀寫資料。根據業務流程的實施和實現可以配置成同步呼叫或非同步呼叫。需要注意的是,響應時間會根據外部系統的穩定狀況進行改變,所以通過適當的使用超時來保護Java EE應用程式和中介軟體也是非常重要的。
下面這3種情況是經常出現問題和效能降低的地方:
1.同步和相繼呼叫太多的外部系統。
2.在Java EE客戶端應用程式和外部系統之間連結超時,使資料丟失或者值太高導致客戶端執行緒被卡住,從而導致多米拉效應。
3.超時,但程式仍正常執行,可是中介軟體不處理這種奇怪的路徑。
最後,建議多進行負面測試,這意味著需要“人為”創造產生這些問題的條件,用來測試應用程式和中介軟體之間是如何處理外部系統錯誤。
4.缺乏適當的資料庫SQL調優和容量規劃
大家可能會對這一個感到驚奇:資料庫問題。大多數Java EE企業系統是依賴關係型資料庫處理複雜的業務流程。一個基礎紮實穩固的資料庫環境可以確保IT環境有規模的增長,來支援日益不斷擴大的業務。
在實際中,與資料庫相關的效能問題是很常見的。由於多數資料庫事務處理都是由JDBC資料來源執行的(包括關係持久化API,例如Hibernate)。而效能問題最初都會表現為執行緒阻塞。
以下是我在10年的工作中,經常出現的關於資料庫方面的問題(以Oracle資料庫為例):
1.孤立的,長時間執行的SQL。主要表現為執行緒阻塞、SQL沒有進行優化、缺少索引、非最佳的執行計劃、返回大量資料集等等。
2.表或行級資料鎖定。當提交一個雙階段事務模型時(例如,臭名昭著的Oracle可疑事務)。Java EE容器可能會留下一些未處理的事務等待最後的提交或回滾,留下的資料鎖能觸發效能問題,直到最後的鎖被移除。例如中介軟體斷電或者伺服器崩潰都可能引起這些情況發生。
3.缺乏合理規範的資料庫管理工具。例如Oracle裡面的REDO logs,資料庫資料檔案等。磁碟空間不足,日誌檔案不旋轉等都會觸發較大的效能問題和斷電情況。
建議:
1.合理的容量規劃,包括負載和效能測試都是必不可少的,優化資料環境和及時發現問題。
2.如果是使用Oracle資料庫,確保DBA團隊定期審查AWR報告,尤其是在上下關聯的事件和根源分析過程中。
3.使用JVM執行緒儲存和AWR報告查明SQL執行緩慢的原因或者使用監控工具來做。
4.加強“操作”方面的資料庫環境(磁碟空間、資料檔案、重做日誌、表空間等)以適當的監視和報警。如果不這麼做,會讓客戶端IT環境出現較多的斷電情況和花許多時間進行故障調修。
5.特定應用程式效能問題
下面關注的是比較嚴重的Java EE應用程式問題。關於特定應用程式效能問題,總結了以下幾個點:
1.執行緒安全的程式碼問題
2.通訊API缺少超時設定
3.I/O、JDBC或者關係型API資源管理問題
4.缺乏適當的資料快取
5.資料快取過度
6.過多的日誌記錄
6.Java EE中介軟體調優問題
一般Java EE中介軟體都已經夠用了,只是缺少必要的優化。大多數Java EE容器都能有多種方案供你的應用程式和業務程式選擇。
如果沒有進行適當的調整和實踐,那麼Java EE容器可能會處於一種消極的狀態。
下圖是檢視和檢查列表示例:
7.主動監控不足
缺乏監控,並不會帶來實際效能問題,但它會影響你對Java EE平臺效能和健康狀況的瞭解。最終,這個環境可以達到一個破發點,這可能會暴露出一些缺陷和問題(JVM的記憶體洩漏,等等)。
以我的經驗來看,如果一開始不進行監控,而是執行幾個月或者幾年後再進行,平臺穩定性將大打折扣。
也就是說,改善現有的環境永遠都不會晚。下面是一些建議:
1.複查現有Java EE環境監測能力和找到需改進的地方。
2.監測方案應該儘可能的覆蓋整個環境。
3.監控方案應該符合容量規劃程式。
8.公共基礎設施硬體飽和
這個問題經常在有太多的Java EE中介軟體環境隨著JVM程式被部署到現有硬體上面時看到。太多的JVM程式對有限的物理CPU核心來說是一個真正的程式效能殺手。另外,隨著客戶端業務的增長,硬體方面也需要再次考慮。
9.網路延遲
最後一個影響效能問題的是網路,網路問題時不時的都會發生,如路由器、交換機和DNS伺服器失敗。更常見的是在一個高度分散的IT環境中定期或間歇性延遲。下面圖片中的例子是一個位於同一區域的Weblogic叢集通訊與Oracle資料庫伺服器之間的延遲。
間歇或定期的延遲會觸發一些重要的效能問題,以不同的方式影響Java EE應用程式。
1.因為大量的fetch迭代(網路傳入和傳出),涉及大資料集的資料查詢問題的應用會非常受網路延遲的影響
2.應用程式在處理外部系統大資料負載(例如XML資料)時也會很受網路延遲的影響,會在傳送和接收響應時產生巨大的響應間隔。
3.Java EE容器複製過程(叢集)也會受到影響,並且會讓故障轉移功能(如多播或單播資料包損失)處於風險中。
JDBC行資料“預取”、XML資料壓縮和資料快取可以減少網路延遲。在設計一個新的網路拓撲時,應該仔細檢查這種網路延遲問題。
希望本文能夠幫助您理解一些常見的效能問題和壓力點,每個IT環境都是獨一無二的,所以文中提到的問題不一定會是您遇到的,您可以把您遇到的問題拿出來和大家一起分享一下!