Java EE性能的十大問題

jopen 12年前發布 | 86K 次閱讀 Java EE J2EE Java開發

        英文來自:Top 10 Causes of Java EE Enterprise Performance Problems

        本文作者是一名有 10 多年經驗的高級系統架構師,他的主要專業領域是 Java EE、中間件和 JVM 技術。他在性能優化和提升方面也有很深刻的見解,下面他將和大家分享一下常見的 10 個影響 Java EE 性能問題。

        1. 缺乏正確的容量規劃

        容量規劃是一個全面的和發展的過程標準,預測當前和未來的 IT 環境容量需求。制定合理的容量規劃不僅會確保和跟蹤當前 IT 生產能力和穩定性,同時也會確保新項目以最小的風險部署到現有的生產環境中。硬件、中間件、JVM、調整等在項目部署之前就應該準備好。

        2. Java EE 中間件環境規范不足

        “沒有規矩,不成方圓”。第二個比較普遍的原因是 Java EE 中間件或者基礎架構不規范。在項目初始,新平臺上面沒有制定合理的規范,導致系統穩定性差。這會增加客戶成本,所以花時間去制定合理的 Java EE 中間件環境規范是必須的。這項工作應與初始容量規劃迭代相結合。

        3. Java 虛擬機垃圾回收過度

        各位對“java.lang.OutOfMemoryError”這個錯誤信息是不是很熟悉呢?由于 JVM 的內存空間過度消耗(Java 堆、本機堆等)而拋出的異常。

        垃圾收集問題并不一定會表現為一個 OOM 條件,過度的垃圾收集可以理解成是 JVM GC 線程在短時間里進行輕微或超量收集集合數據而導致的 JVM 暫停時間很長和性能下降。可能有以下幾個原因:

  • 與 JVM 的負載量和應用程序內存占用量相比,Java 堆可能選擇的太小。
  • JVM GC 策略使用不合理。
  • 應用程序靜態或動態內存占用量太大,不適合在 32 位 JVM 上使用。
  • JVM OldGen 隨著時間推移,泄漏越來越嚴重,而 GC 在幾個小時或者幾天后才發現。
  • JVM PermGen 空間(只有 HotSpot VM)或本機堆隨著時間推移會泄露是一個非常普遍的問題;OOM 的錯誤往往是觀察一段時間后,應用程序進行動態調動。
  • YoungGen 和 OldGen 的比例空間與你的應用程序不匹配。
  • Java 堆在 32 位的 VM 上太大,導致本機堆溢出,具體可以表現為 OOM 試著去鏈接一個新的 Java EE 應用程序、創建一個新的 Java 線程或者需要計算本地內存分配任務。
  • </ul>

            建議:

    • 觀察和深入理解 JVM 垃圾回收。啟動 GC,根據健康合理的評估來提供所有的數據。
    • 記住,GC 方面的相關問題不會在開發中或者功能測試時發現,它需要在多用戶高負載的測試環境下發現。
    • </ul>

              4. 與外部系統集成過多或過少

              導致 Java EE 性能差的第四個原因是高分布式系統,典型案例是電信 IT 環境。在這個環境中,一個中間件領域(例如,服務總線)很少會做所有的工作,而僅僅是把一些業務“委托”給其他部分,例如產品質量,客戶資料和訂單管理, 到其他 Java EE 中間件平臺或遺留系統中,如支持各種不同的負載類型和通信協議的大型機。

              這樣的外部系統調用意味著客戶端的 Java EE 應用程序觸發創建或重用套接字鏈接從外部系統中讀寫數據。根據業務流程的實施和實現可以配置成同步調用或異步調用。需要注意的是,響應時間會根據外部系統 的穩定狀況進行改變,所以通過適當的使用超時來保護 Java EE 應用程序和中間件也是非常重要的。

              下面這 3 種情況是經常出現問題和性能降低的地方:

      • 同步和相繼調用太多的外部系統。
      • 在 Java EE 客戶端應用程序和外部系統之間鏈接超時,使數據丟失或者值太高導致客戶端線程被卡住,從而導致多米拉效應。
      • 超時,但程序仍正常執行,可是中間件不處理這種奇怪的路徑。
      • </ul>

                最后,建議多進行負面測試,這意味著需要“人為”創造產生這些問題的條件,用來測試應用程序和中間件之間是如何處理外部系統錯誤。

                5. 缺乏適當的數據庫 SQL 調優和容量規劃

                大家可能會對這一個感到驚奇:數據庫問題。大多數 Java EE 企業系統是依賴關系型數據庫處理復雜的業務流程。一個基礎扎實穩固的數據庫環境可以確保 IT 環境有規模的增長,來支持日益不斷擴大的業務。

                在實際中,與數據庫相關的性能問題是很常見的。由于多數數據庫事務處理都是由 JDBC 數據源執行的(包括關系持久化 API,例如 Hibernate)。而性能問題最初都會表現為線程阻塞。

                以下是我在 10 年的工作中,經常出現的關于數據庫方面的問題(以 Oracle 數據庫為例):

        • 孤立的,長時間運行的 SQL。主要表現為線程阻塞、SQL 沒有進行優化、缺少索引、非最佳的執行計劃、返回大量數據集等等。
        • 表或行級數據鎖定。當提交一個雙階段事務模型時(例如,臭名昭著的 Oracle 可疑事務)。Java EE 容器可能會留下一些未處理的事務等待最后的提交或回滾,留下的數據鎖能觸發性能問題,直到最后的鎖被移除。例如中間件斷電或者服務器崩潰都可能引起這些情 況發生。
        • 缺乏合理規范的數據庫管理工具。例如 Oracle 里面的 REDO logs,數據庫數據文件等。磁盤空間不足,日志文件不旋轉等都會觸發較大的性能問題和斷電情況。
        • </ul>

                  建議:

          • 合理的容量規劃,包括負載和性能測試都是必不可少的,優化數據環境和及時發現問題。
          • 如果是使用 Oracle 數據庫,確保 DBA 團隊定期審查 AWR 報告,尤其是在上下關聯的事件和根源分析過程中。
          • 使用 JVM 線程存儲和 AWR 報告查明 SQL 運行緩慢的原因或者使用監控工具來做。
          • 加強“操作”方面的數據庫環境(磁盤空間、數據文件、重做日志、表空間等)以適當的監視和報警。如果不這么做,會讓客戶端 IT 環境出現較多的斷電情況和花許多時間進行故障調修。
          • </ul>

                    6. 特定應用程序性能問題

                    下面關注的是比較嚴重的 Java EE 應用程序問題。關于特定應用程序性能問題,總結了以下幾個點:

            1. 線程安全的代碼問題
            2. 通信 API 缺少超時設置
            3. I/O、JDBC 或者關系型 API 資源管理問題
            4. 缺乏適當的數據緩存
            5. 數據緩存過度
            6. 過多的日志記錄
            7. </ol>

                      7. Java EE 中間件調優問題

                      一般 Java EE 中間件都已經夠用了,只是缺少必要的優化。大多數 Java EE 容器都能有多種方案供你的應用程序和業務進程選擇。

                      如果沒有進行適當的調整和實踐,那么 Java EE 容器可能會處于一種消極的狀態。

                      下圖是視圖和檢查列表示例:

                      8. 主動監控不足

                      缺乏監控,并不會帶來實際性能問題,但它會影響你對 Java EE 平臺性能和健康狀況的了解。最終,這個環境可以達到一個破發點,這可能會暴露出一些缺陷和問題(JVM 的內存泄漏,等等)。

                      以我的經驗來看,如果一開始不進行監控,而是運行幾個月或者幾年后再進行,平臺穩定性將大打折扣。

                      也就是說,改善現有的環境永遠都不會晚。下面是一些建議:

              1. 復查現有 Java EE 環境監測能力和找到需改進的地方。
              2. 監測方案應該盡可能的覆蓋整個環境。
              3. 監控方案應該符合容量規劃進程。
              4. </ol>

                        9. 公共基礎設施硬件飽和

                        這個問題經常在有太多的 Java EE 中間件環境隨著 JVM 進程被部署到現有硬件上面時看到。太多的 JVM 進程對有限的物理 CPU 核心來說是一個真正的程序性能殺手。另外,隨著客戶端業務的增長,硬件方面也需要再次考慮。

                        10. 網絡延遲

                        最后一個影響性能問題的是網絡,網絡問題時不時的都會發生,如路由器、交換機和 DNS 服務器失敗。更常見的是在一個高度分散的 IT 環境中定期或間歇性延遲。下面圖片中的例子是一個位于同一區域的 Weblogic 集群通信與 Oracle 數據庫服務器之間的延遲。

                        間歇或定期的延遲會觸發一些重要的性能問題,以不同的方式影響 Java EE 應用程序。

                1. 因為大量的 fetch 迭代(網絡傳入和傳出),涉及大數據集的數據查詢問題的應用會非常受網絡延遲的影響
                2. 應用程序在處理外部系統大數據負載(例如 XML 數據)時也會很受網絡延遲的影響,會在發送和接收響應時產生巨大的響應間隔。
                3. Java EE 容器復制過程(集群)也會受到影響,并且會讓故障轉移功能(如多播或單播數據包損失)處于風險中。
                4. </ol>

                          JDBC 行數據“預取”、XML 數據壓縮和數據緩存可以減少網絡延遲。在設計一個新的網絡拓撲時,應該仔細檢查這種網絡延遲問題。

                          希望本文能夠幫助您理解一些常見的性能問題和壓力點,每個 IT 環境都是獨一無二的,所以文中提到的問題不一定會是您遇到的,您可以把您遇到的問題拿出來和大家一起分享一下!

                  來自: CSDN
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!