開篇思考
- 爲什麼需要服務追蹤?
- 分佈式事務幾種實現方式?
- 哪種追蹤方式性能更優?
爲什麼需要服務追蹤
在微服務架構下,由於進行了服務拆分,一次請求往往需要涉及多個服務,
每個服務可能是由不同的團隊開發,使用了不同的編程語言,還有可能部署在不同的機器上,分佈在不同的數據中心。
服務跟蹤系統可以跟蹤記錄一次用戶請求都發起了哪些調用,經過哪些服務處理,並且記錄每一次調用所涉及的服務的詳細信息,
通過查看完整的調用鏈路,形成拓補圖可以更加直觀的瞭解業務,也可以針對當前的系統進行分析,是否需要擴容、優化接口、失敗緩解,
還有通過日誌快速定位是調用失敗的環節。
服務追蹤的實際應用
捋清業務
我們都知道,在一般場景下,我們很難直觀的瞭解系統的運行、業務的流程,因爲傳統的都是文字需求說明和枯燥的代碼。通過鏈路追蹤,可以
根據調用鏈路來捋清楚服務間的調用關係,如果 API 設計符合規範,甚至可以直觀的瞭解調用的服務作用。這對於剛剛接觸系統的開發人員
十分重要。
分析耗時
鏈路的基本功能,服務間的調用耗時記錄,如果服務耗時過長,會影響整體的用戶體驗,甚至會拋出超時異常等,這樣的情況在微服務架構中也是
時有發生。
可視化錯誤
微服務調用鏈路發生錯誤,可以直觀的顯示查看,定位到被調用服務的接口,及時排查微服務中錯誤原因。
優化鏈路:
顯示完整的調用鏈路,根據業務分析合理性、可讀性、健壯性,是否重複調用某一個服務,是否鏈路過長,有沒有可以優化的,鏈路是否清晰。
有些場景比較複雜,比如數據中心比較分散,服務分佈在不同的數據中心,但是服務中心之間因爲地域原因,距離遠,延遲高,這可能不符合設計
要求,因此就要根據鏈路來找到最近的數據中心,然後配置調用最近的數據中心的服務。
生成網絡拓撲:
通過服務追蹤系統中記錄的鏈路信息,可以生成一張系統的網絡調用拓撲圖,它可以反映系統都依賴了哪些服務,
以及服務之間的調用關係是什麼樣的,可以一目瞭然。除此之外,在網絡拓撲圖上還可以把服務調用的詳細信息也標出來,
也能起到服務監控的作用。
skywalking & zipkin
zipkin + sleuth 之前一直是 pringcloud 官方的推薦,我在springcloud demo 中也使用過,總體用下來追蹤和分析都滿足需求,
但是功能相對 skywalking 而言比較簡單,沒有skywalking 強大。集成也是比較簡單,只要引入相關依賴,然後啓動zipkin server 端就可以
在頁面上面查看。
今天主要看下 skywalking 的安裝和使用
安裝
推薦下載編譯好的源碼:http://skywalking.apache.org/downloads/
- linux 下載 tar 解壓後運行
- window下載 zip 解壓後運行
當然還有其他幾種方式,比如 github 源碼下載編譯,docker 運行,這裏不多說,看自己方便哪種,如果懂docker 其實docker 纔是最佳選擇,
如果沒玩過推薦直接下載壓縮包,簡單。
接下來以 window 爲例,修改application.yml 文件,換成自己喜歡的數據庫。我使用的是 es:
環境要求:
- JDK8+
- Elasticsearch 6.x
- 8080,10800,11800,12800 端口不被佔用
結合 springcloud 或者其他項目
- java 命令,添加 vm option: -javaagent:/path/agent/skywalking-agent.jar
- Linux Tomcat 修改 tomcat/bin/catalina.sh,在首行加入如下信息.
CATALINA_OPTS="$CATALINA_OPTS -javaagent:/path/to/skywalking-agent/skywalking-agent.jar"; export CATALINA_OPTS
- Windows Tomcat 修改 tomcat/bin/catalina.bat,在首行加入如下信息.
set "CATALINA_OPTS=-javaagent:/path/to/skywalking-agent/skywalking-agent.jar"
下面是我的 idea 配置:
啓動dashboard
找到 bin 目錄下 startup.bat ,雙擊打開,注意端口不要佔用,否則就要自己修改配置文件該端口號
啓動後,如果頁面上有自己的服務信息,就說明切入成功。說到這裏要對 agent 工作原理說下。
工作原理介紹 java agent
先說一下它的用途,在JDK1.5以後,我們可以使用agent技術構建一個獨立於應用程序的代理程序(即爲Agent),用來協助監測、
運行甚至替換其他JVM上的程序。使用它可以實現虛擬機級別的AOP功能。
- 分爲 premain agentmain
/**
* 以vm參數的方式載入,在Java程序的main方法執行之前執行
*/
public static void premain(String agentArgs, Instrumentation inst);
/**
* 以Attach的方式載入,在Java程序啓動後執行
*/
public static void agentmain(String agentArgs, Instrumentation inst);
- 在META-INF目錄下創建 MANIFEST.MF 文件.用來指定主函數入口,
Agent-Class
和Premain-Class
程序領域(id:think-holy)
作者:holy 程序汪一隻