阿里P8架構(gòu)師詳解Java性能調(diào)優(yōu)策略

一、性能測(cè)試


Ⅰ.測(cè)試方法

  1. 微基準(zhǔn)性能測(cè)試
  • 可以精準(zhǔn)定位到某個(gè)模塊或者某個(gè)方法的性能問(wèn)題,例如對(duì)比一個(gè)方法使用同步實(shí)現(xiàn)和非同步實(shí)現(xiàn)的性能差異
  1. 宏基準(zhǔn)性能測(cè)試
  • 宏基準(zhǔn)性能測(cè)試是一個(gè)綜合測(cè)試,需要考慮到測(cè)試環(huán)境、測(cè)試場(chǎng)景和測(cè)試目標(biāo)
  • 測(cè)試環(huán)境:模擬線上的真實(shí)環(huán)境
  • 測(cè)試場(chǎng)景:在測(cè)試某個(gè)接口時(shí),是否有其他業(yè)務(wù)的接口也在平行運(yùn)行,進(jìn)而造成干擾
  • 測(cè)試目標(biāo)
    • 可以通過(guò)吞吐量和響應(yīng)時(shí)間來(lái)衡量系統(tǒng)是否達(dá)標(biāo),如果不達(dá)標(biāo),就需要進(jìn)行優(yōu)化
    • 如果達(dá)標(biāo),就繼續(xù)加大測(cè)試的并發(fā)數(shù),探底接口的TPS
    • 除了關(guān)注接口的吞吐量和響應(yīng)時(shí)間外,還需要關(guān)注CPU、內(nèi)存和IO的使用率情況

Ⅱ.干擾因素

1.熱身問(wèn)題

①. 在Java編程語(yǔ)言和環(huán)境中,.java文件編譯成.class文件后,需要通過(guò)解析器將字節(jié)碼轉(zhuǎn)換成本地機(jī)器碼才能運(yùn)行

②. 為了節(jié)約內(nèi)存和執(zhí)行效率,代碼在最初被執(zhí)行時(shí),解析器會(huì)率先解析執(zhí)行這段代碼

③. 隨著代碼被執(zhí)行的次數(shù)增加,當(dāng)JVM發(fā)現(xiàn)某個(gè)方法或代碼塊運(yùn)行得很頻繁時(shí),就會(huì)把這些代碼認(rèn)定為熱點(diǎn)代碼

  • 為了提高熱點(diǎn)代碼的執(zhí)行效率,在運(yùn)行時(shí),JVM將通過(guò)即時(shí)編譯器(JIT)把這些代碼編譯成與本地平臺(tái)相關(guān)的機(jī)器碼
  • 并進(jìn)行各層次的優(yōu)化,然后存儲(chǔ)在內(nèi)存中,之后每次運(yùn)行代碼時(shí),直接從內(nèi)存中獲取

④. 因此在剛開始運(yùn)行的階段,JVM會(huì)花費(fèi)很長(zhǎng)的時(shí)間來(lái)全面優(yōu)化代碼,后面就能以最高性能運(yùn)行了

2. 測(cè)試結(jié)果不穩(wěn)定

①. 不穩(wěn)定因素:機(jī)器其他進(jìn)程的影響、網(wǎng)絡(luò)波動(dòng)、JVM GC的不確定性
①. 解決方案:通過(guò)多次測(cè)試,將測(cè)試結(jié)果求平均,只要能保證平均值在一個(gè)合理的范圍之內(nèi),并且波動(dòng)不大即可

3. 多JVM

①. 任意一個(gè)JVM都擁有整個(gè)系統(tǒng)的資源使用權(quán)
②. 如果一臺(tái)機(jī)器上只部署單獨(dú)的一個(gè)JVM,在做性能測(cè)試時(shí),測(cè)試結(jié)果會(huì)很好,但一臺(tái)機(jī)器上有多個(gè)JVM,則不一定
③. 盡量避免線程環(huán)境一臺(tái)機(jī)器部署多個(gè)JVM

二、性能分析


1.完成性能測(cè)試之后,需要輸出一份性能測(cè)試報(bào)告,測(cè)試結(jié)果需要包括

  • 測(cè)試接口的吞吐量和響應(yīng)時(shí)間(平均、最大、最小)
  • 服務(wù)器的CPU、內(nèi)存、磁盤IO、網(wǎng)絡(luò)IO使用率、JVM的GC情況

2.通過(guò)觀察性能指標(biāo),可以發(fā)現(xiàn)性能瓶頸,再通過(guò)自下而上的方式分析查找問(wèn)題

  • 首先從操作系統(tǒng)層面,查看系統(tǒng)的CPU、內(nèi)存、磁盤IO、網(wǎng)絡(luò)IO的使用率是否存在異常
  • 再通過(guò)命令查找異常日志,通過(guò)分析日志,尋找導(dǎo)致性能瓶頸的原因
  • 還可以從Java應(yīng)用的JVM層面下手,查看JVM的GC頻率以及內(nèi)存分配情況是否存在異常
  • 如果系統(tǒng)和JVM層面都沒(méi)有出現(xiàn)異常情況,可以查看應(yīng)用服務(wù)業(yè)務(wù)層是否存在性能瓶頸
    • 例如Java編程的問(wèn)題、讀寫數(shù)據(jù)瓶頸

3.分析查找性能問(wèn)題可以采用自下而上的方式,而解決性能問(wèn)題,一般采用自上而下的方式逐級(jí)優(yōu)化

三、性能調(diào)優(yōu)


思路業(yè)務(wù)調(diào)優(yōu) -> 編程調(diào)優(yōu) -> 系統(tǒng)調(diào)優(yōu)

Ⅰ. 優(yōu)化代碼

1.應(yīng)用層的問(wèn)題代碼往往會(huì)因?yàn)楹谋M系統(tǒng)資源而暴露出來(lái)

2.例如某段代碼導(dǎo)致內(nèi)存溢出,這往往是將JVM的內(nèi)存耗盡了

  • 這會(huì)引發(fā)JVM頻繁地發(fā)生GC,導(dǎo)致CPU居高不下,此時(shí)也會(huì)耗盡系統(tǒng)的CPU資源

3.還有一些非問(wèn)題代碼導(dǎo)致的性能問(wèn)題,比較難以發(fā)現(xiàn)

  • 例如如果對(duì)LinkedList進(jìn)行for循環(huán)遍歷,每次循環(huán)獲取元素時(shí),都會(huì)遍歷一次list,讀效率很低
  • 優(yōu)化方案:可以采用Iterator

Ⅱ. 優(yōu)化設(shè)計(jì)

1.面向?qū)ο笥泻芏嘣O(shè)計(jì)模式,可以用于優(yōu)化業(yè)務(wù)層以及中間件層的代碼設(shè)計(jì),進(jìn)而達(dá)到精簡(jiǎn)代碼和提高整體性能的目的

2.例如單例模式在頻繁創(chuàng)建對(duì)象的場(chǎng)景中,可以共享一個(gè)對(duì)象,減少頻繁創(chuàng)建和銷毀對(duì)象帶來(lái)的性能開銷

Ⅲ. 優(yōu)化算法

1.合適的算法可以大大提升系統(tǒng)性能

2.例如在不同的場(chǎng)景中,使用合適的查找算法可以降低時(shí)間復(fù)雜度

Ⅳ. 時(shí)間換空間

1.如果系統(tǒng)對(duì)查詢的速度沒(méi)有很高的要求,但對(duì)存儲(chǔ)空間要求苛刻,可以考慮用時(shí)間換空間

2.例如String的intern方法,可以將重復(fù)率比較高的數(shù)據(jù)存儲(chǔ)在常量池,重復(fù)使用相同的對(duì)象,大大節(jié)省內(nèi)存空間

  • 但由于常量池使用的是HashMap類型,如果存儲(chǔ)數(shù)據(jù)過(guò)多,就會(huì)導(dǎo)致查詢性能下降

Ⅴ. 空間換時(shí)間

1.使用存儲(chǔ)空間來(lái)提升訪問(wèn)速度
2.例如MySQL的分庫(kù)分表

Ⅵ. 參數(shù)調(diào)優(yōu)

1.根據(jù)業(yè)務(wù)場(chǎng)景,合理地設(shè)置JVM的內(nèi)存空間和GC算法
2.另外,合理地設(shè)置Web容器的線程池大小和Linux操作系統(tǒng)的內(nèi)核參數(shù)

四、兜底策略


1.性能優(yōu)化策略,主要為了提高系統(tǒng)性能,而兜底策略,主要為了確保系統(tǒng)的穩(wěn)定性

2.限流

  • 對(duì)系統(tǒng)的入口設(shè)置最大訪問(wèn)限制,參考性能測(cè)試中探底的接口TPS
  • 同時(shí)采用熔斷措施,友好地返回沒(méi)有成功的請(qǐng)求

3.智能橫向擴(kuò)容

  • 當(dāng)訪問(wèn)量超過(guò)某一個(gè)閾值時(shí),系統(tǒng)可以根據(jù)需求自動(dòng)橫向擴(kuò)容

4.提前擴(kuò)容

  • 常用于高并發(fā)系統(tǒng),例如瞬時(shí)搶購(gòu)
  • 此時(shí)智能橫向擴(kuò)容無(wú)法滿足大量發(fā)生在瞬間的請(qǐng)求

5.Kubernetes可以實(shí)現(xiàn)智能橫向擴(kuò)容和提前擴(kuò)容Docker服務(wù)

五、總結(jié)


寫在最后


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容