作者:欒文飛 高階軟件工程師
一、背景介紹
Sermant是一個主打服務(wù)治理領(lǐng)域的Java Agent框架,在服務(wù)治理中難免會有針對業(yè)務(wù)流量進(jìn)行解析和處理的過程,此類服務(wù)治理能力將會對微服務(wù)的服務(wù)能力產(chǎn)生一定的性能影響,作為一個基于Java Agent技術(shù)做服務(wù)治理的框架,我們需要在保證服務(wù)治理能力生效的同時,極小的影響微服務(wù)原有的服務(wù)性能。
雖然基于Java Agent的服務(wù)治理和基于SDK的服務(wù)治理在其原理上有所不同,但也避免不了微服務(wù)治理過程中產(chǎn)生對微服務(wù)原有性能的影響,基于Java Agent服務(wù)治理方式的相較于SDK的服務(wù)治理方式免去了侵入式的代碼開發(fā),是一種運行時技術(shù),所以還需要考慮更多方面性能優(yōu)化問題,例如在啟動時間,運行時增強性能開銷等,本文將以Sermant的SpringBoot 注冊插件的性能測試及優(yōu)化過程為例,分享在Java Agent場景如何進(jìn)行更好的性能測試優(yōu)化及在Java Agent下需要著重注意的性能陷阱。
SpringBoot 注冊插件為SpringBoot應(yīng)用提供服務(wù)注冊發(fā)現(xiàn)能力,可用于在不修改原有代碼的前提下快速從ESB架構(gòu)演進(jìn)為微服務(wù)架構(gòu),在該插件中包含針對域名的替換能力,服務(wù)注冊發(fā)現(xiàn)能力,請求的超時重試等,為架構(gòu)的成功演進(jìn),原有架構(gòu)中基于域名的請求調(diào)用,將會被基于注冊信息的請求調(diào)用(通過該插件的服務(wù)注冊發(fā)現(xiàn)能力,獲取服務(wù)提供者注冊的信息)所取代,如下圖所示:
在域名處理的過程是必然會參與到調(diào)用過程中的,這是服務(wù)治理能力對業(yè)務(wù)性能影響的典型場景。
二、測試方案
眾所周知,Java Agent程序和被增強應(yīng)用運行時同進(jìn)程,Java Agent程序最重要的是不能對被掛載的應(yīng)用產(chǎn)生異常影響,導(dǎo)致應(yīng)用不可用,所以Sermant在運行時的處理性能及穩(wěn)定性等做多方面的測試考量。在針對微服務(wù)進(jìn)行測試的過程中,我們往往只需要關(guān)注該微服務(wù)的性能即可,通過壓力測試來檢驗微服務(wù)的服務(wù)提供能力,由于服務(wù)治理能力并不直接提供服務(wù),我們更多地需要關(guān)注在開啟服務(wù)治理能力時,對微服務(wù)本身服務(wù)提供能力的影響,所以我們在測試方案中需要進(jìn)行對比測試來評估服務(wù)治理能力的好壞。
本對照測試中,我們通過壓力測試讓系統(tǒng)達(dá)到極限場景(consumer端的CPU已經(jīng)到達(dá)瓶頸),來分析攜帶Sermant并啟用服務(wù)治理能力時,對應(yīng)用原有服務(wù)提供能力的影響,此處采用兩種部署方案:
-
不攜帶Sermant,基于網(wǎng)關(guān)的場景,是架構(gòu)改造前的運行模式
-
攜帶Sermant的場景,是遷移后的微服務(wù)架構(gòu)運行模式
注:在這種對比測試中,基于Java Agent的服務(wù)治理只需要對攜帶Java Agent程序和不攜帶Java Agent程序的場景進(jìn)行對照測試即可,無需兩套代碼進(jìn)行對照測試。
由于Java Agent程序和被增強應(yīng)用處于統(tǒng)一進(jìn)程,資源共享,基于上述兩種部署方案進(jìn)行測試,以不攜帶Java Agent程序作為測試分析的對照組,就可以很清晰的看出引入Java Agent程序后產(chǎn)生的影響,并可根據(jù)對照結(jié)果進(jìn)行優(yōu)化,應(yīng)用于Sermant上,就可以很容易的分析出Sermant的服務(wù)治理能力對微服務(wù)本身服務(wù)提供能力帶來的影響。
三、性能分析
由于需要針對應(yīng)用發(fā)起的請求通過字節(jié)碼增量的方式做域名的替換,SpringBoot 注冊插件通過對HttpClient、Openfeign、Okhttp等http客戶端進(jìn)行了字節(jié)碼增強,我們根據(jù)上一章節(jié)中的測試方案對該插件提供的服務(wù)治理能力進(jìn)行了測試,下面我們以HttpClien為例通過CPU火焰圖來講述如何在Java Agent場景下分析性能瓶頸:
在性能調(diào)優(yōu)過程中,我們可通過CPU火焰圖來分析性能瓶頸,火焰圖可以稱之為性能問題分析的"X光",可以很一針見血的看出在程序運行中哪些代碼片段產(chǎn)生了異常的CPU占用??梢詤⒖肌妒褂没鹧鎴D(FlameGraph)分析程序性能》進(jìn)行學(xué)習(xí),當(dāng)然,采集CPU火焰圖的方式很多,我們只需要學(xué)會如何看懂火焰圖即可。
分析步驟
1. 找到字節(jié)碼增強邏輯的CPU占用
在分析過程中,首先需要找到字節(jié)碼增強時選中的被增強方法(本文場景增強方法為InternalHttpClient::doExecute),字節(jié)碼增強需要被增強程序的原有方法調(diào)用觸發(fā),所以也可以很清晰的在CPU火焰圖中可以看到,Sermant實現(xiàn)的邏輯調(diào)用棧在被增強方法之上,在字節(jié)碼增強邏輯執(zhí)行結(jié)束后,被增強方法還會繼續(xù)執(zhí)行。
所以除被增強方法執(zhí)行的調(diào)用棧及CPU時間片占用外,皆為字節(jié)碼增強所引入邏輯,在性能優(yōu)化中需著重關(guān)注。
2. 分析異常占用
根據(jù)CPU火焰圖原理,找出字節(jié)碼增強部分,找出異常占用CPU時間片的調(diào)用棧,并進(jìn)行程序的優(yōu)化,如下圖所示紅框選擇部分,皆為字節(jié)碼增強中引入的邏輯,占用了非常多的CPU時間片,由于字節(jié)碼增強程序和被增強程序,這種異常的占用,將會嚴(yán)重影響原程序的性能,在針對Java Agent場景的優(yōu)化中可著重優(yōu)化。
通過上述步驟,我們可以一目了然的看到我們通過Java Agent程序引入的CPU額外占用,具體占用原因本文就不一一分析。
四、性能陷阱
基于上述兩個章節(jié)的測試和分析方法,在本文的最后,列舉出在Java Agent開發(fā)過程中經(jīng)常會遇到的性能陷阱,這里也給出解決方式,可以在開發(fā)中注意:
|減少反射使用
在字節(jié)碼增強開發(fā)過程中,很多情況下,如果類加載器不同,針對被增強應(yīng)用的類和方法往往需要通過反射去獲取并使用,在我們的性能分析中,反射是一個CPU占用的巨大陷阱,在有些被BootstrapClassLoader加載的類增強時,甚至反射占用了一個方法調(diào)用30%以上的CPU時間片。
下圖選中方法中,反射占用該方法調(diào)用中的大部分CPU時間片:
但是由于類加載器的限制,有些反射是必須要使用的,我們也可以通過一定的手段進(jìn)行優(yōu)化,比如緩存通過反射獲取的類和方法,在字節(jié)碼增強中,多次觸發(fā)增強邏輯時減少反射占用CPU時間片非常有效。
通過上述步驟優(yōu)化后,通過火焰圖來看,效果是非常顯著的:
|注意字節(jié)碼增強插樁選擇
在做字節(jié)碼增強時的增強點選擇很重要,字節(jié)碼增強添加Transformer后運行時分為兩種情況:
-
transform:針對尚未被類加載器加載的類,如果添加Transformer,在類被加載時就會觸發(fā)字節(jié)碼的轉(zhuǎn)換.
-
retransform:針對已經(jīng)被類加載器加載的類,如果添加了Transformer,則需要被重新加載后再進(jìn)行字節(jié)碼的轉(zhuǎn)換。
Java中被BootstrapClassLoader加載的類,如果想要進(jìn)行字節(jié)碼增強,就需要使用第二種字節(jié)碼轉(zhuǎn)換的方式,可想而知,如果重新加載類再進(jìn)行轉(zhuǎn)換必然沒有在類第一次加載時就進(jìn)行轉(zhuǎn)換的效率高。
除上述原因之外,在增強啟動類加載器加載的類時,由于雙親委派機制的限制(只能向上委托,不能向下委托),往往都是需要大量使用反射(用于調(diào)用其他類加載器加載的類)來實現(xiàn)增強邏輯。
上文中也講到,不加節(jié)制的使用反射將會通過Java Agent程序嚴(yán)重影響被增強應(yīng)用的性能,所以在開發(fā)Java Agent時,需要謹(jǐn)慎選擇增強的類,非必要不增強被啟動類加載器加載的類。
上述兩點是在Java Agent開發(fā)過程中最容易發(fā)生的向被增強應(yīng)用引入的性能陷阱,除此之外,Java Agent也是由Java所開發(fā),在開發(fā)過程中也需要注意不要引入常見的性能陷阱。
Sermant作為專注于服務(wù)治理領(lǐng)域的字節(jié)碼增強框架,致力于提供高性能、可擴展、易接入的服務(wù)治理體驗,并會在每個版本中做好性能、功能、體驗的看護(hù),廣泛歡迎大家的加入。
Sermant官網(wǎng):https://sermant.io
GitHub倉庫地址:https://github.com/huaweicloud/Sermant
添加Sermant小二(微信號:sermant-support)加入社區(qū)交流群
或掃碼加入Sermant社區(qū)交流群
原文標(biāo)題:技術(shù)速遞 | Java Agent場景性能測試分析優(yōu)化經(jīng)驗分享
文章出處:【微信公眾號:華為DevCloud】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
-
華為
+關(guān)注
關(guān)注
215文章
34263瀏覽量
251041
原文標(biāo)題:技術(shù)速遞 | Java Agent場景性能測試分析優(yōu)化經(jīng)驗分享
文章出處:【微信號:華為DevCloud,微信公眾號:華為DevCloud】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論