java系統如何做業務性能優化

java系統如何做業務性能優化

前言


屏幕快照 2020-02-07 21.47.11.png


基本上每個系統都有一個在整個生命週期都需要討論的話題“性能”。在業務初期,“野蠻生長”是第一要務,只要能滿足用戶性能,堆機器、堆人力、堆數據庫等,能直接解決的都無需上升到專門的優化專題。


經常聽到的一句話就是,機器性能的提升,很少有人去關注系統調優了。當然,在服務器性能飆升導致工程師越來越少關注底層優化邏輯。



業務性能優化


那麼爲什麼還要那麼關注業務性能優化? 一方面,時刻保持性能優化,在技術方案設計期間、在編碼期間、在上線運行期間、在業務維護期間,都應該追求極致的體驗,可以降低系統消耗節省成本,可以節省用戶時間提升用戶效率。

另外一方面,性能優化應該是工程師自身的一種基本素質。系統保持相對優化狀態,對於穩定性、效能都是有着重要影響。


性能優化方法論


這裏簡單介紹一下我對性能優化的看法。



工具化

要保證能快速定位系統的瓶頸,就應該有一套合適的工具幫助快速定位到性能薄弱點。那有一套調用鏈的整體觀測方法,就能輕易實現這個目的了。

google公司的Dapper就是一套分佈式下的跟蹤系統,具體論文:http://bigbully.github.io/Dapper-translation/


分佈式跟蹤鏈路


基本上大型互聯網公司都會基於Dapper實現一套自身的分佈式鏈路系統,通過這個系統的調用鏈,就很容易分析出系統在每個接口和模塊上的耗時,進而可以更清晰的定位接口,進一步分析代碼查看其RT耗時及制定出相應的優化方案。


屏幕快照 2020-02-07 19.47.18.png


如上圖所示,阿里雲提供的鷹眼能力,可以看到在每個應用上的調用耗時。


spring調用攔截

上面說的,是可以做到系統間的調用分析,對於單個應用來說,可能使用應用內部的一些攔截器來實現整體調用情況分析,可能會更爲高效、具備針對性。


屏幕快照 2020-02-07 20.08.41.png


以上是我用的springaop的攔截器,可以打印出每個bean的消耗。進而可以分析具體某個bean的方法耗時已經耗時在哪個邏輯裏。


最佳實踐

通常來說,每個優化都是要CASE BY CASE的,但是從經驗上來說,有幾個優化方法是屢試不爽的,也基本上可以覆蓋80%的場景。

批處理

很多業務場景,都需要有列表頁,比如商品列表、用戶列表、訂單列表等,如果使用單接口的話,往往就需要循環取數,RT則容易就變成了O(N),用批處理則可以將取數優化成O(1)。經驗上來看,一次內存計算1毫秒已經頂天了,但是一次RPC至少10毫秒左右。


屏幕快照 2020-02-07 20.26.58.png


從實際調用來看,一次北京到上海的RT耗時大約在60毫秒左右。因此解決RPC調用是全部優化需要首先考慮的一個問題。


緩存處理

只要滿足數據非強一致性,則可以使用緩存來降級,減少大量的DB和內存計算。比如商品詳情,基本上是不會有什麼變化,因此商品數據無需頻繁去DB中取,我們只要將商品對象緩存起來,直接取緩存數據即可。緩存還有更多的用法,比如用作臨時存儲等。當然緩存還有數據一致性的問題、多級緩存的問題,這裏就不再贅述,後續將對緩存重點再講解一波。緩存的RT一般1毫秒左右,接口RT則一般至少10毫秒以上,因此用緩存空間來換取時間還是穩賺的。


異步處理

異步處理相對前面一些措施來說會比較複雜一些,首先需要對業務理解透徹,哪些是可以拆分成異步化處理的,哪些是必須同步處理的,其次是要對異步有深刻理解,異步化本身相對同步來說,會增加一個複雜度。以下是同步轉異步的僞代碼。

屏幕快照 2020-02-07 21.49.04.png


屏幕快照 2020-02-07 21.49.25.png


當然,異步是有代價的,可以說是一種用空間換時間的辦法,同時,異步的編程複雜度也會高很多。這裏大家可以看看rxjava,後續會繼續介紹rxjava在生產上的最佳實踐。


非必要情況下,還是慎用異步的編程模式,但是架構上可以採用異步的模式,比如支付成功後發送用戶消息、調用物流接口,則可以用系統消息來解耦。



總結

性能優化是一個業務持續集成類似的模式,也是需要持續做性能,性能優化是伴隨業務生命週期的。優化的方式和角度都很多,這裏只是總結出我在做中大型系統的自己的思考。

發佈了344 篇原創文章 · 獲贊 25 · 訪問量 52萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章