導讀:做性能分析聽到最多的歪理就是,服務做水準、垂直擴容、分表分庫、讀寫分離、XX 中間件、資源靜态化等等但是歸根到底這些方案都是為了盡可能減少對資料庫的通路以及堆棧的釋放,提高資料庫 IO 的讀寫速度和程式的運作效率。
系統都是逐漸演進的,一個系統在運作中必須是根據場景逐漸地提高優化性能。高并發就是對資源的節約的考驗,這種考驗除了更換優秀和先進的技術,優化架構,還在于從小處出發,對盡可能節約的資源進行節約。
而在一個系統的資料通路中,系統的瓶頸往往是來自于資料庫,是以我們要盡可能減少對資料庫的通路!
最近一段時間粉絲可能留意到,技術号一直沒有更新多少技術文章。因為近期都在做一直在做性能優化。
在業務子產品在并發量起來以後,接口的性能瓶頸就愈發變得明顯。
配置解析和函數路由服務接口性能堆棧分析
本篇主要針對配置布局資源檔案過大,導緻接口耗時過長問題分析解決。
排查性能如果從代碼層面出發少不了堆棧分析,但是目前大部分服務都為了便于服務擴容、更新都做了微服務處理,日志分析排查免不了通過鍊路 ID 追蹤日志《微服務分布式架構中,如何實作日志鍊路跟蹤?》
在《鍊路日志追蹤》中提到通過 restTemplate、Openfeign 的形式通路其他服務的接口時,就會攜帶起始位置生成的 traceId、spanId 到下一個服務單元。但是沒有詳細實作,這裡做下簡單補充便于後面了解與使用。
閱讀 Spring-Web 源碼,對于遠端接口的調用攔截可以實 ClientHttpRequestInterceptor
攔截用戶端 HTTP 請求。這個接口的實作可以注冊到 RestTemplate ,以修改傳出的 ClientHttpRequest 和/或傳入的 ClientHttpResponse 。攔截器的主要入口點是 intercept(HttpRequest, byte[], ClientHttpRequestExecution) 。
計算 RPC 接口耗時與日志記錄,這樣在做接口分析的時候可以針對性能較差、耗時高的接口有針對性性排查分析。
遠端服務的接口性能暫時不做分析,目前很明确耗時:1528ms 應該存在很大的性能問題。
但是目前隻統計出遠端接口耗時是遠遠不夠的,我們需要知道接口總耗時以及對堆棧分析才能精準定位到問題。
記錄 HTTP 監控資訊
這裡需要補充下不是所有的接口我們都需要捕捉和統計分析,我們可以統一接口規範。如頁面請求統一以<code>/data/</code>開頭,RPC 接口統一以<code>/api/</code>開頭這樣可以分别區分兩則的統計資訊,避免記錄錯亂。
上面👆🏻的兩處的處理目前也隻能精确度到目前 HTTP 請求有哪些 PRC 接口請求?每個 PRC 接口請求耗時多少?作為核心服務不太會去關系業務服務的接口細節,如果需要針對 PRC 接口的主服務做進步性能分析即可。
是以還需要進步統計出所有 RPC 接口的總耗時和次總次數。
通過“線程變量”傳遞 RPC 接口的請求的次數。記得先前有類似出路過服務之間的認證問題也是通過請求頭傳遞。《Spring Cloud中如何保證各個微服務之間調用的安全性?》
累計完請求數量繼續傳遞下去,以此類推來統計 RPC 接口的請求總數
這裡做了簡單門檻值限制,背景不難想到:如果一個接口頻繁調用另外一個服務超過 20、30 次此時,我們就應該考慮服務之間資料同步或者映射問題。
是以在計算 RPC 接口的請求總次數加了門檻值限制,若 RPC 調用次數超出範圍則輸出警告日志
至于鍊路追蹤日志的展示,自己使用就不用太關注圖形化樣式問題,這裡建議直接使用 Thymeleaf 模闆引擎進行渲染展示,也就有了文章開頭的圖檔
對于問題分析我們首先能遇到的總是一個較大的問題,在算法中我們常會用分治算法。一言以蔽之:将一個難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破。
回顧整個處理思路
微服務日志埋點處理,記錄鍊路日志并統計
監聽 HTTP 請求後,記錄微服務服務之間 RPC 接口耗時
監聽 HTTP 請求後,記錄 RPC 接口深度(請求次數)
記錄 RPC 請求總總耗時與總占比
至此算是完成了我們做鍊路日志分析的第一步:統計分析 HTTP 請求所觸發的外部服務的性能消耗。
原文:微服務架構 | 如何利用好日志做性能分析?