Java Agent場景性能測試分析優化經驗分享

来源:https://www.cnblogs.com/huaweiyun/archive/2023/03/03/17176201.html
-Advertisement-
Play Games

摘要:本文將以Sermant的SpringBoot 註冊插件的性能測試及優化過程為例,分享在Java Agent場景如何進行更好的性能測試優化及在Java Agent下需要著重註意的性能陷阱。 作者:欒文飛 高級軟體工程師 一、背景介紹 Sermant是一個主打服務治理領域的Java Agent框架 ...


摘要:本文將以Sermant的SpringBoot 註冊插件的性能測試及優化過程為例,分享在Java Agent場景如何進行更好的性能測試優化及在Java Agent下需要著重註意的性能陷阱。

作者:欒文飛 高級軟體工程師

一、背景介紹

Sermant是一個主打服務治理領域的Java Agent框架,在服務治理中難免會有針對業務流量進行解析和處理的過程,此類服務治理能力將會對微服務的服務能力產生一定的性能影響,作為一個基於Java Agent技術做服務治理的框架,我們需要在保證服務治理能力生效的同時,極小的影響微服務原有的服務性能。

雖然基於Java Agent的服務治理和基於SDK的服務治理在其原理上有所不同,但也避免不了微服務治理過程中產生對微服務原有性能的影響,基於Java Agent服務治理方式的相較於SDK的服務治理方式免去了侵入式的代碼開發,是一種運行時技術,所以還需要考慮更多方面性能優化問題,例如在啟動時間,運行時增強性能開銷等,本文將以Sermant的SpringBoot 註冊插件的性能測試及優化過程為例,分享在Java Agent場景如何進行更好的性能測試優化及在Java Agent下需要著重註意的性能陷阱。

SpringBoot 註冊插件為SpringBoot應用提供服務註冊發現能力,可用於在不修改原有代碼的前提下快速從ESB架構演進為微服務架構,在該插件中包含針對功能變數名稱的替換能力,服務註冊發現能力,請求的超時重試等,為架構的成功演進,原有架構中基於功能變數名稱的請求調用,將會被基於註冊信息的請求調用(通過該插件的服務註冊發現能力,獲取服務提供者註冊的信息)所取代,如下圖所示:

在功能變數名稱處理的過程是必然會參與到調用過程中的,這是服務治理能力對業務性能影響的典型場景。

二、測試方案

眾所周知,Java Agent程式和被增強應用運行時同進程,Java Agent程式最重要的是不能對被掛載的應用產生異常影響,導致應用不可用,所以Sermant在運行時的處理性能及穩定性等做多方面的測試考量。在針對微服務進行測試的過程中,我們往往只需要關註該微服務的性能即可,通過壓力測試來檢驗微服務的服務提供能力,由於服務治理能力並不直接提供服務,我們更多地需要關註在開啟服務治理能力時,對微服務本身服務提供能力的影響,所以我們在測試方案中需要進行對比測試來評估服務治理能力的好壞。

本對照測試中,我們通過壓力測試讓系統達到極限場景(consumer端的CPU已經到達瓶頸),來分析攜帶Sermant並啟用服務治理能力時,對應用原有服務提供能力的影響,此處採用兩種部署方案

  • 不攜帶Sermant,基於網關的場景,是架構改造前的運行模式
  • 攜帶Sermant的場景,是遷移後的微服務架構運行模式

註:在這種對比測試中,基於Java Agent的服務治理只需要對攜帶Java Agent程式和不攜帶Java Agent程式的場景進行對照測試即可,無需兩套代碼進行對照測試。

由於Java Agent程式和被增強應用處於統一進程,資源共用,基於上述兩種部署方案進行測試,以不攜帶Java Agent程式作為測試分析的對照組,就可以很清晰的看出引入Java Agent程式後產生的影響,並可根據對照結果進行優化,應用於Sermant上,就可以很容易的分析出Sermant的服務治理能力對微服務本身服務提供能力帶來的影響。

三、性能分析

由於需要針對應用發起的請求通過位元組碼增量的方式做功能變數名稱的替換,SpringBoot 註冊插件通過對HttpClient、Openfeign、Okhttp等http客戶端進行了位元組碼增強,我們根據上一章節中的測試方案對該插件提供的服務治理能力進行了測試,下麵我們以HttpClien為例通過CPU火焰圖來講述如何在Java Agent場景下分析性能瓶頸:

在性能調優過程中,我們可通過CPU火焰圖來分析性能瓶頸,火焰圖可以稱之為性能問題分析的"X光",可以很一針見血的看出在程式運行中哪些代碼片段產生了異常的CPU占用。可以參考《使用火焰圖(FlameGraph)分析程式性能》進行學習,當然,採集CPU火焰圖的方式很多,我們只需要學會如何看懂火焰圖即可。

分析步驟

1. 找到位元組碼增強邏輯的CPU占用

在分析過程中,首先需要找到位元組碼增強時選中的被增強方法(本文場景增強方法為InternalHttpClient::doExecute),位元組碼增強需要被增強程式的原有方法調用觸發,所以也可以很清晰的在CPU火焰圖中可以看到,Sermant實現的邏輯調用棧在被增強方法之上,在位元組碼增強邏輯執行結束後,被增強方法還會繼續執行。

所以除被增強方法執行的調用棧及CPU時間片占用外,皆為位元組碼增強所引入邏輯,在性能優化中需著重關註。

2. 分析異常占用

根據CPU火焰圖原理,找出位元組碼增強部分,找出異常占用CPU時間片的調用棧,併進行程式的優化,如下圖所示紅框選擇部分,皆為位元組碼增強中引入的邏輯,占用了非常多的CPU時間片,由於位元組碼增強程式和被增強程式,這種異常的占用,將會嚴重影響原程式的性能,在針對Java Agent場景的優化中可著重優化

通過上述步驟,我們可以一目瞭然的看到我們通過Java Agent程式引入的CPU額外占用,具體占用原因本文就不一一分析。

四、性能陷阱

基於上述兩個章節的測試和分析方法,在本文的最後,列舉出在Java Agent開發過程中經常會遇到的性能陷阱,這裡也給出解決方式,可以在開發中註意:

減少反射使用

在位元組碼增強開發過程中,很多情況下,如果類載入器不同,針對被增強應用的類和方法往往需要通過反射去獲取並使用,在我們的性能分析中,反射是一個CPU占用的巨大陷阱,在有些被BootstrapClassLoader載入的類增強時,甚至反射占用了一個方法調用30%以上的CPU事件片。

下圖選中方法中,反射占用該方法調用中的大部分CPU時間片:

但是由於類載入器的限制,有些反射是必須要使用的,我們也可以通過一定的手段進行優化,比如緩存通過反射獲取的類和方法,在位元組碼增強中,多次觸發增強邏輯時減少反射占用CPU時間片非常有效。

Method method = METHOD_CACHE.get(methodKey);  
if (method != null) {  
 return Optional.of(method);  
}  
method = clazz.getDeclaredMethod(methodName, paramsType);  
METHOD_CACHE.put(methodKey, method);  

通過上述步驟優化後,通過火焰圖來看,效果是非常顯著的:

註意位元組碼增強插樁選擇

在做位元組碼增強時的增強點選擇很重要,位元組碼增強添加Transformer後運行時分為兩種情況:

  • transform:針對尚未被類載入器載入的類,如果添加Transformer,在類被載入時就會觸發位元組碼的轉換。
  • retransform:針對已經被類載入器載入的類,如果添加了Transformer,則需要被重新載入後再進行位元組碼的轉換。

Java中被BootstrapClassLoader載入的類,如果想要進行位元組碼增強,就需要使用第二種位元組碼轉換的方式,可想而知,如果重新載入類再進行轉換必然沒有在類第一次載入時就進行轉換的效率高。

除上述原因之外,在增強啟動類載入器載入的類時,由於雙親委派機制的限制(只能向上委托,不能向下委托),往往都是需要大量使用反射(用於調用其他類載入器載入的類)來實現增強邏輯。

上文中也講到,不加節制的使用反射將會通過Java Agent程式嚴重影響被增強應用的性能,所以在開發Java Agent時,需要謹慎選擇增強的類,非必要不增強被啟動類載入器載入的類。

上述兩點是在Java Agent開發過程中最容易發生的向被增強應用引入的性能陷阱,除此之外,Java Agent也是由Java所開發,在開發過程中也需要註意不要引入常見的性能陷阱。

結束語

Sermant作為專註於服務治理領域的位元組碼增強框架,致力於提供高性能、可擴展、易接入的服務治理體驗,並會在每個版本中做好性能、功能、體驗的看護,廣泛歡迎大家的加入。

Sermant官網:https://sermant.io

GitHub倉庫地址:https://github.com/huaweicloud/Sermant

 

點擊關註,第一時間瞭解華為雲新鮮技術~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 簡介 chatgpt-java是一個OpenAI的Java版SDK,支持開箱即用。目前以支持官網全部Api。支持最新版本GPT-3.5-Turbo模型以及whisper-1模型。增加chat聊天對話以及語音文件轉文字,語音翻譯。 開源地址:https://github.com/Grt1228/cha ...
  • 下載安裝包 Prometheus windows_exporter Grafana 下載地址:https://share.weiyun.com/D9sdiWoC 工作原理 Exporter 監控工具,獲取數據 Prometheus 普羅米修斯時序資料庫,用來存儲和查詢監控數據 Grafana 儀錶盤 ...
  • 哈嘍兄弟們,今天我們來試試,如何只用13行代碼,給抖音APP視頻自動點贊! 前因後果 事情是這樣的,昨晚表弟晚上一兩點了,房間燈還亮著,原來是還在用手機刷某音視頻,我搶過手機一看,好家伙,連刷十個都是美女,喜歡列表也全是MM。 我看他手動點贊手都點累了,乾脆熬個夜,給他寫一個自動點贊的代碼,今晚他就 ...
  • MyBatis緩存 mybatis – MyBatis 3 | cache MyBatis 一級緩存全詳解(一) MyBatis 內置了一個強大的事務性查詢緩存機制,它可以非常方便地配置和定製。 為了使它更加強大而且易於配置,我們對 MyBatis 3 中的緩存實現進行了許多改進。 1.一級緩存 1 ...
  • for迴圈 迴圈的作用與分類 作用:讓代碼更加高效的重覆運行 分類:for迴圈和while迴圈 for迴圈結構 for 臨時變數 in 可迭代對象: 重覆執行的代碼1 重覆執行的代碼2 ... 可迭代對象 = 一個容器或者序列 # 遍歷字元串 for i in 'Python': print(i) ...
  • 現象 系統根據指定的日期範圍(LocalDateTime)查詢資料庫,結果與直接將SQL語句查詢不一致,系統查詢的並不是期望日期範圍的數據。 通過 LocalDateTime、LocaDate、LocalDate 作為時間插入數據時,時間不對 解決 更換 mysql 的驅動包版本在 8.0.22及以 ...
  • Spring提供的事務使用起來很方便,一個@Transactional註解就搞定全部,但是如果不註意,也會踩坑 提到事務就應該想到至少以下幾點: 1、在事務方法中加鎖,可能會導致鎖失效 無論是JVM自帶的鎖,還是分散式鎖,都有可能出現沒鎖住的情況 原因是解鎖先於事務提交,一旦鎖釋放後其它線程就可以獲 ...
  • 目錄 ElasticSearch 實現分詞全文檢索 - 概述 ElasticSearch 實現分詞全文檢索 - ES、Kibana、IK安裝 ElasticSearch 實現分詞全文檢索 - Restful基本操作 --待發佈 ElasticSearch 實現分詞全文檢索 - Java Spring ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...