前言
鏈路追蹤介紹
對于一個大型的幾十個,幾百個微服務構成的微服務架構系統,通常會遇到下面的一系列問題。
- 如何串聯整個調用鏈路,快速定位問題?
- 如何澄清各個微服務之間的依賴關系?
- 如何進行各個微服務接口的性能分析?
- 如何追蹤各個業務流程的調用處理順序?
Skywalking介紹
Skywalking是一個國產的開源框架,2015年有吳晟個人開源,2017年加入Apache孵化器,國人開源的產品,主要開發人員來自于華為,2019年4月17日Apache董事會批準SkyWalking成為頂級項目,支持Java、.Net、NodeJs等探針,數據存儲支持Mysql、Elasticsearch等,跟Pinpoint一樣采用字節碼注入的方式實現代碼的無侵入,探針采集數據粒度粗,但性能表現優秀,且對云原生支持,目前增長勢頭強勁,社區活躍。
Skywalking是分布式系統的應用程序性能監視工具,專為微服務,云原生架構和基于容器(Docker,K8S,Mesos)架構而設計,它是一款優秀的APM(Application Performance Management)工具,包括了分布式追蹤,性能指標分析和服務依賴分析等。
鏈路追蹤框架對比
目前市面上開源的APM系統主要有CAT、Zipkin、Pinpoint、SkyWalking,大都是參考Google的Dapper實現的
功能和技術方案對比
- Zipkin是Twitter開源的調用鏈路分析工具,目前基于Spingcloud sleuth得到了廣泛的應用,特點是輕量,部署簡單。
- Pinpoint:一個韓國團隊開源的產品,運用了字節碼增強技術,只需要在啟動時添加啟動參數即可,對代碼無侵入,目前支持Java和PHP語言,底層采用HBase來存儲數據,探針收集的數據粒度非常細,但性能損耗大,因其出現的時間較長,完成度也很高,應用的公司較多
- Skywalking是本土開源的基于字節碼注入的調用鏈路分析以及應用監控分析工具,特點是支持多種插件,UI功能較強,接入端無代碼侵入。
- CAT是由國內美團點評開源的,基于Java語言開發,目前提供Java、C/C++、Node.js、Python、Go等語言的客戶端,監控數據會全量統計,國內很多公司在用,例如美團點評、攜程、拼多多等,CAT跟下邊要介紹的Zipkin都需要在應用程序中埋點,對代碼侵入性強。
下載
APM包下載地址: https://skywalking.apache.org/downloads/
這邊下載的是 v9.0.0 版本
APM 全稱為: Application Performance Management (應用程序性能監視工具),下載的APM包里面就已經包含了skywalking 服務端和UI前端,UI前端是一個web項目,用于展示鏈路追蹤的數據;
注意事項:skywalking在8.8.0版本以后將agent單獨拆分了出來,所以若要使用8.8.0版本以后的,需要下載apm和agent兩個壓縮包。因為我選擇的是9.0.0版本。剛剛已經下載了apm包,所以還需要在下載 agent 的壓縮包,
agent包下載地址:https://dlcdn.apache.org/skywalking/java-agent/8.11.0/apache-skywalking-java-agent-8.11.0.tgz
將這2個文件下載完并且解壓縮后會得到2個目錄:
apache-skywalking-apm-bin
skywalking-agent
配置
打開 .\apache-skywalking-apm-bin\config\application.yml
文件
skywalking-web-ui服務會占用 8080 端口, 修改端口可以修改webapp/webapp.yml
啟動成功后會啟動兩個服務,一個是skywalking-oap-server,一個是skywalking-web-ui,
skywalking-oap-server服務啟動后會暴露11800 和 12800 兩個端口:
11800
:收集監控數據的端口12800
:接受前端請求的端口
修改端口可以通過 config/applicaiton.yml 文件來修改
agent 配置
修改探針默認配置 skywalking-agent/config/agent.config
# 將127.0.0.1修改為OAP所在的ip地址
collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}# 默認值為:-1 (全量收集鏈路),在訪問量較少時,鏈路全量收集不會對系統帶來太大負擔,能夠完整的觀測到系統的運行狀況。但是在訪問量較大時,全量的鏈路收集,對鏈路收集的客戶端(agent探針)、服務端(SkyWalking OAP)、存儲器(例如說 Elastcsearch)都會帶來較大的性能開銷,甚至會影響應用的正常運行。在訪問量級較大的情況下,往往會選擇抽樣采樣,只收集部分鏈路信息。agent.sample_n_per_3_secs 配置項,設置每 3 秒可收集的鏈路數據的數量。
agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:1}
通過docker安裝skywalking 9.0.0
docker中,服務端和 ui是分開的,所以需要安裝2個docker
# 服務端docker run --name oap --restart always -d -p 11800:11800 -p 12800:12800 apache/skywalking-oap-server:9.0.0# Ui 端
docker run --name oap-ui --restart always -d -e SW_OAP_ADDRESS=http://192.168.31.250:12800 -p 8880:8080 apache/skywalking-ui:9.0.0
啟動
根據系統不同,windows雙擊 startup.bat
,linux 通過命令 nohup ./startup.sh &
后臺運行
因為我用的windows,啟動后會開啟2個黑窗口
在瀏覽器輸入地址: http://localhost:8080
即可訪問 skywalking
追蹤測試
準備2個服務,user 服務 和 order 服務,通過openfeign遠程調用,
order 服務的controller層代碼如下
import com.alibaba.cloud.client.OpenFeignOrderClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/open/feign")
public class OpenFeignController {@Autowiredprivate OpenFeignOrderClient openFeignOrderClient;/*** 調用遠程openFeign 接口* @return*/@RequestMapping("/getOrderList")public String getOrderList() {return openFeignOrderClient.getOrderList();}
}
openFeign 接口 ,將此文件放到公共模塊,user和order服務都引用這個公共模塊;
import com.alibaba.cloud.fallback.OpenFeignFallBack;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;@FeignClient(value = "order-demo",path = "order",fallback = OpenFeignFallBack.class)
public interface OpenFeignOrderClient {/*** 獲取訂單列表* @return*/@RequestMapping("/getOrderList")String getOrderList();
}
降級回調處理,也放到公共模塊中
import com.alibaba.cloud.client.OpenFeignOrderClient;
import org.springframework.stereotype.Component;/*** 降級回調類*/
@Component
public class OpenFeignFallBack implements OpenFeignOrderClient {@Overridepublic String getOrderList() {return "openFeign遠程調用暫時不可用,可能的原因是遠程服務未開啟,或者是遠程服務超時或者報錯導致";}
}
order服務添加一個controller,實現openFeign接口,其中,通過代碼int i=1/0;
來拋出異常,
import com.alibaba.cloud.client.OpenFeignOrderClient;
import com.alibaba.cloud.dto.UserDto;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/order")
public class OrderController implements OpenFeignOrderClient {// openFeign 的實現接口@Overridepublic String getOrderList() {int i=1/0;return "get Order list success! ";}
}
在啟動前,兩個服務都需要添加vm參數
user
-javaagent:D:\java\skywallking\skywalking-agent\skywalking-agent.jar
-Dskywalking.agent.service_name=user_app
order
-javaagent:D:\java\skywallking\skywalking-agent\skywalking-agent.jar
-Dskywalking.agent.service_name=order_app
skywalking-agent.jar
是什么文件
剛剛我們不是下載了2個壓縮包嗎,skywalking-agent.jar
這個文件就在另一個壓縮包內
啟動user服務和order服務
啟動后,在skywalking上就可以看到這2個服務了
在瀏覽器訪問地址http://localhost:8089/open/feign/getOrderList
, 毫無疑問,報錯了,因為有降級路基,所以頁面上直接顯示了友好提示,
但order服務確實是報錯了
接下來我們進入到user服務的鏈路追蹤
然后切換到 Topology 頁,這里可以看直觀地看到服務之間的調用關系,第一個User表示是客戶端,誰調用誰都能看的很清楚; 但是必須先調用過之后 skywalking 才知道是誰調用的誰,沒調用的話,是看不到他們之間的關系的,右上角有個調用深度,可以查看最多5級調用,因為我這邊只有3個,所以調整到3就夠了
然后切換到 Trace 頁,這里才是真正的鏈路追蹤,可以看到每個服務之間調用的 controller 層接口; 紅色表示報錯的接口,藍色表示正常訪問的接口;
然后點擊最下面的controller 鏈接,就可以看到拋出的具體異常了
除零異常,跟order的控制臺報的錯誤是一樣一樣的