SpringCloud 分布式追蹤

[toc]

一、基礎(chǔ)知識

1.1 為什么要使用分布式追蹤

微服務(wù)在架構(gòu)冠息、敏捷開發(fā)、快速部署孕索、去中心化逛艰、組件化等方面帶來便捷和優(yōu)勢。但是隨著微服務(wù)框架落地搞旭,分布式架構(gòu)和微服務(wù)架構(gòu)給系統(tǒng)性能分析和問題定位帶來非常大挑戰(zhàn)散怖。因此能夠匯聚業(yè)務(wù)系統(tǒng)各處理環(huán)節(jié)的實時數(shù)據(jù),實現(xiàn)對應(yīng)用的全鏈路性能監(jiān)測的微服務(wù)監(jiān)控工具必不可少肄渗。

基于微服務(wù)體系之下構(gòu)建的業(yè)務(wù)系統(tǒng)存在的問題基本上分為三類:

  • 故障定位難镇眷,一個簡單操作,其背后可能是由多個微服務(wù)共同完成的翎嫡,這些微服務(wù)也由不同的團隊去負責欠动。一旦出現(xiàn)問題,最壞情況下我們也許需要這十幾個團隊一起來解決問題。
  • 鏈路梳理難具伍,應(yīng)用沒有形成應(yīng)用拓撲翅雏,不知道自己的服務(wù)下游會影響其他哪些人。
  • 資源浪費多人芽,容量預(yù)估難望几。對于一些服務(wù),其消耗的cpm和memory可能連10%不到萤厅,遠遠沒有充分利用物理機橄抹。這其實和容量預(yù)估關(guān)聯(lián),過大或者過小估算峰值的機器容量惕味,都是浪費楼誓。

APM主要的目的就是解決上面所說的問題,主要的手段是通過收集赦拘、存儲慌随、分析、分布式系統(tǒng)中的調(diào)用事件數(shù)據(jù)躺同,協(xié)助開發(fā)運營人員進行故障診斷阁猜、容量預(yù)估、性能瓶頸定位以及調(diào)用鏈路梳理蹋艺。

市面上APM產(chǎn)品眾多剃袍,選擇合適的APM產(chǎn)品主要從以下需求進行對比選型:

  • 代碼的侵入性
  • 探針的性能消耗
  • 全面的調(diào)用鏈路數(shù)據(jù)分析
  • 可擴展性

本文選擇skywalking作為微服務(wù)APM框架,skywalking相當于其他APM產(chǎn)品在性能消耗方面更有優(yōu)勢捎谨,且代碼零入侵民效、可擴展性強并且其支持動態(tài)配置可以很好的和微服務(wù)框架進行集成。


1.2 分布式追蹤實現(xiàn)原理

1.2.1 術(shù)語

  • Trace 一次分布式調(diào)用的鏈路
  • Span 一次本地或者遠程方法的調(diào)用
  • Annotation 附加在 Span 上的日志信息
  • Sampling 采樣率(客戶端按照比例將埋點信息提交給服務(wù)端

1.2.2 原理

分布式追蹤理論主要包括以下兩個關(guān)鍵點:

  • 為了實現(xiàn)分布式追蹤涛救,當請求發(fā)送到分布式系統(tǒng)的入口端點時畏邢,分布式服務(wù)追蹤框架為該請求創(chuàng)建一個唯一的追蹤標識,同時在分布式系統(tǒng)內(nèi)部流轉(zhuǎn)時检吆,追蹤框架始終保持傳遞該唯一標識舒萎,直到返回給請求方為止,這個唯一標識就是Trace ID蹭沛,而一次完整的調(diào)用鏈路就是Trace臂寝。通過Trace ID我們就能將請求鏈路進行關(guān)聯(lián)起來。
  • 為了統(tǒng)計各單位的時間延遲摊灭,當我們請求達到各個服務(wù)組件咆贬、或者處理邏輯到達某個狀態(tài)時,分布式服務(wù)追蹤框架創(chuàng)建一個唯一標識來標記它的開始帚呼、具體過程以及結(jié)束掏缎,該標識就是Span。

1.3 OpenTracing?

1.3.1 OpenTracing簡介

OpenTracing:通過為流行的平臺提供一致的御毅,富有表現(xiàn)力的根欧,==供應(yīng)商中立==的API,OpenTracing使開發(fā)人員可以輕松地通過O(1)配置更改添加(或切換)跟蹤實現(xiàn)端蛆。OpenTracing還為OSS檢測和特定于平臺的跟蹤幫助程序庫提供了通用語言凤粗。OpenTracing盡力讓監(jiān)控一個分布式調(diào)用過程簡單化。通過OpenTracing可以快速配置一個監(jiān)控系統(tǒng)今豆。

OpenTracing數(shù)據(jù)模型

1.3.2 OpenTracing規(guī)范

OpenTracing 僅定義了一套開放規(guī)范和API用于在應(yīng)用開發(fā)中設(shè)置埋點嫌拣,實際的抓取存儲日志、分析統(tǒng)計展現(xiàn)都由兼容 OpenTracing 的監(jiān)控產(chǎn)品完成呆躲。

數(shù)據(jù)模型

OpenTracing 設(shè)計圍繞兩個核心概念開展:

  • Trace:一條完整的調(diào)用鏈异逐,通過傳遞全局唯一的TraceID追蹤整個調(diào)用過程。
  • Span: 記錄調(diào)用鏈某個具體服務(wù)或方法的執(zhí)行情況插掂,通常包含調(diào)用開始時間灰瞻、持續(xù)時間、調(diào)用方辅甥、被調(diào)用方酝润、關(guān)鍵日志、異常璃弄、操作上下文等要销。

下圖為SpringCloud微服務(wù)一次完整調(diào)用鏈,Span的因果關(guān)系圖:


操作間引用

從上圖數(shù)據(jù)模型間關(guān)系可以看出夏块,一個操作可能引用0個或多個具有觸發(fā)關(guān)系的操作上下文疏咐。OpenTracing定義了兩種類型的引用:

  • ChildOf: 一個操作可以是另一個操作的子操作,在一個ChildOf引用中脐供,父操作在一定程度上依賴于子操作浑塞。一下場景符合ChildOf關(guān)系:
  1. 一次Feign調(diào)用的服務(wù)端操作是客戶端操作的子操作
  2. 一個表示SQL插入的操作是一個ORM save方法的子操作
  3. 一個父操作可以有多個同步進行(可能是分布式)的父操作,該父操作會在執(zhí)行期限內(nèi)聚合所有子操作的結(jié)果返回給用戶
  • FollowsFrom: 有些父操作不以任何方式依賴它們的子操作的結(jié)果政己。在這種場景下酌壕,子操作僅僅由父操作觸發(fā)。

二匹颤、skywalking

2.1 skywalking簡介

skywalking是分布式系統(tǒng)的應(yīng)用性能檢測工具,提供分布式追蹤托猩、服務(wù)網(wǎng)格遙測分析印蓖、度量聚合和可視化一體化解決方案。

2.1.1 skywalking功能

skywalking提供如下核心功能:

  • 多種監(jiān)控手斷京腥,支持語言探針和service mesh獲得監(jiān)控數(shù)據(jù)
  • 支持多種語言探針赦肃,包括Java、NET、Python和NodeJS等
  • 輕量高效他宛,無需大數(shù)據(jù)平臺和服務(wù)支持
  • 模塊化船侧。UI、存儲厅各、集群管理有多種機制可選
  • 優(yōu)秀的可視化解決方案镜撩。

2.1.2 skywalking架構(gòu)

skywalking整體架構(gòu)

skywalking整體架構(gòu)可以分為四部分:

  • Skywalking Agent:語言探針,通過無侵入的方式收集鏈路數(shù)據(jù)队塘,發(fā)送給OAP Server
  • Skywalking OAP: 鏈路數(shù)據(jù)收集器袁梗,負責接收 Agent 發(fā)送的 數(shù)據(jù)信息,然后進行分析(Analysis Core) 憔古,存儲到外部存儲器( Storage )遮怜,最終提供查詢( Query )功能。
  • Storage :鏈路追蹤數(shù)據(jù)存儲鸿市。目前支持 ES锯梁、MySQL、Sharding Sphere焰情、TiDB陌凳、H2 等多種存儲器。
  • Skywalking UI:可視化平臺烙样,提供一體化解決方案冯遂。

2.2 skywalking 安裝部署

我們使用apache-skywalking-apm-es7-8.7.0 + ES7.x + nacos 配置中心進行skywalking環(huán)境搭建。ES7.x + nacos安裝搭建這里不在贅述谒获。

2.2.1 下載安裝

step1 下載skywalking APM包

# 創(chuàng)建目錄
$ mkdir -p /Users/skywalking
$ cd /Users/skywalking

# 下載
$ wget https://www.apache.org/dyn/closer.cgi/skywalking/java-agent/8.8.0/apache-skywalking-java-agent-8.8.0.tgz

step2 解壓

# 解壓
$ tar -zxvf apache-skywalking-apm-es7-8.7.0.tar.gz
$ cd  apache-skywalking-apm-bin-es7
[root@localhost apache-skywalking-apm-bin-es7]# ll

drwxrwxr-x.  9 1001 1002   176 7月  30 21:15 agent  # SkyWalking Agent語言探針插件
drwxr-xr-x.  2 root root   241 12月 24 17:13 bin # OAP Server和Web UI執(zhí)行腳本
drwxr-xr-x. 11 root root  4096 12月 29 16:51 config # OAP Server配置文件
drwxr-xr-x.  2 root root    68 12月 24 17:13 config-examples
-rwxrwxr-x.  1 1001 1002 31480 7月  30 20:32 LICENSE
drwxrwxr-x.  3 1001 1002  4096 12月 24 17:13 licenses
drwxr-xr-x.  2 root root   126 1月  12 11:40 logs # 日志目錄
-rwxrwxr-x.  1 1001 1002 32519 7月  30 20:32 NOTICE
drwxrwxr-x.  2 1001 1002 12288 7月  30 21:34 oap-libs # SkyWalking OAP Server
-rw-rw-r--.  1 1001 1002  1951 7月  30 20:32 README.txt
drwxr-xr-x.  3 root root    30 12月 24 17:13 tools
drwxr-xr-x.  2 root root    53 12月 24 17:31 webapp # SkyWalking UI

核心配置

OAP Server 核心配置
OAP Server 配置采用模塊化配置蛤肌,從集群模式、核心Collector批狱、存儲器裸准、Collector Receiver、動態(tài)配置等提供了多種選擇:

  • 集群模式(cluster)
    Collector支持集群部署赔硫,zookeeper炒俱、kubernetes(如果你的應(yīng)用是部署在容器中的)、consul(GO語言開發(fā)的服務(wù)發(fā)現(xiàn)工具)爪膊、nacos是sw可選的集群管理工具权悟,結(jié)合大家具體的部署方式進行選擇。

cluster:
  selector: ${SW_CLUSTER:standalone}
  standalone:
  # Please check your ZooKeeper is 3.5+, However, it is also compatible with ZooKeeper 3.4.x. Replace the ZooKeeper 3.5+
  # library the oap-libs folder with your ZooKeeper 3.4.x library.
  zookeeper:
    nameSpace: ${SW_NAMESPACE:""}
    hostPort: ${SW_CLUSTER_ZK_HOST_PORT:localhost:2181}
    # Retry Policy
    baseSleepTimeMs: ${SW_CLUSTER_ZK_SLEEP_TIME:1000} # initial amount of time to wait between retries
    maxRetries: ${SW_CLUSTER_ZK_MAX_RETRIES:3} # max number of times to retry
    # Enable ACL
    enableACL: ${SW_ZK_ENABLE_ACL:false} # disable ACL in default
    schema: ${SW_ZK_SCHEMA:digest} # only support digest schema
    expression: ${SW_ZK_EXPRESSION:skywalking:skywalking}
  kubernetes:
    namespace: ${SW_CLUSTER_K8S_NAMESPACE:default}
    labelSelector: ${SW_CLUSTER_K8S_LABEL:app=collector,release=skywalking}
    uidEnvName: ${SW_CLUSTER_K8S_UID:SKYWALKING_COLLECTOR_UID}
  consul:
    serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
    # Consul cluster nodes, example: 10.0.0.1:8500,10.0.0.2:8500,10.0.0.3:8500
    hostPort: ${SW_CLUSTER_CONSUL_HOST_PORT:localhost:8500}
    aclToken: ${SW_CLUSTER_CONSUL_ACLTOKEN:""}
  etcd:
    # etcd cluster nodes, example: 10.0.0.1:2379,10.0.0.2:2379,10.0.0.3:2379
    endpoints: ${SW_CLUSTER_ETCD_ENDPOINTS:localhost:2379}
    namespace: ${SW_CLUSTER_ETCD_NAMESPACE:/skywalking}
    serviceName: ${SW_SCLUSTER_ETCD_ERVICE_NAME:"SkyWalking_OAP_Cluster"}
    authentication: ${SW_CLUSTER_ETCD_AUTHENTICATION:false}
    user: ${SW_SCLUSTER_ETCD_USER:}
    password: ${SW_SCLUSTER_ETCD_PASSWORD:}
  nacos:
    serviceName: ${SW_SERVICE_NAME:"SkyWalking_OAP_Cluster"}
    hostPort: ${SW_CLUSTER_NACOS_HOST_PORT:localhost:8848}
    # Nacos Configuration namespace
    namespace: ${SW_CLUSTER_NACOS_NAMESPACE:"public"}
    # Nacos auth username
    username: ${SW_CLUSTER_NACOS_USERNAME:""}
    password: ${SW_CLUSTER_NACOS_PASSWORD:""}
    # Nacos auth accessKey
    accessKey: ${SW_CLUSTER_NACOS_ACCESSKEY:""}
    secretKey: ${SW_CLUSTER_NACOS_SECRETKEY:""}
  • Collector Core
    Collector 核心配置主要提供通信推盛、采樣率峦阁、TTL配置:
    • 通信方式:collector提供了gRPC和HTTP兩種通信方式,UI使用rest http通信耘成,agent在大多數(shù)場景下使用grpc方式通信榔昔,在語言不支持的情況下會使用http通信驹闰。關(guān)于綁定IP和端口需要注意的一點是,通過綁定IP撒会,agent和collector必須配置對應(yīng)ip才可以正常通信嘹朗。
    • downsampling: 采樣匯總統(tǒng)計維度,會分別按照分鐘诵肛、【小時屹培、天、月】(可選)來統(tǒng)計各項指標數(shù)據(jù)曾掂。
    • TTL:通過設(shè)置TTL相關(guān)配置項可以對數(shù)據(jù)進行自動清理

詳細配置大家可以去Skywalking官網(wǎng)下載介質(zhì)包進行了解惫谤,這里就不貼出來了。

  • 存儲器
    SW支持ES珠洗、ES7溜歪、H2、Mysql许蓖、postgrsql等蝴猪,項目可以根據(jù)實際情況選擇合適存儲器。
storage:
  selector: elasticsearch7
  elasticsearch7:
    nameSpace: ${SW_NAMESPACE:"myyshop_monitor"}
    clusterNodes: ${SW_STORAGE_ES_CLUSTER_NODES:192.168.128.34:9200}
    protocol: ${SW_STORAGE_ES_HTTP_PROTOCOL:"http"}
    connectTimeout: ${SW_STORAGE_ES_CONNECT_TIMEOUT:500}
    socketTimeout: ${SW_STORAGE_ES_SOCKET_TIMEOUT:30000}
    // 省略許多
  • Collector Receiver
    配置監(jiān)控的系統(tǒng)中接受指標數(shù)據(jù)膊爪。支持上傳符合OpenTracing規(guī)范的自定義的監(jiān)控數(shù)據(jù)自阱。
  • 配置中心
    按照Skywalking官網(wǎng)的客戶端搭建方式,基本采取配置agent.properties文件米酬,或者通過java -D 帶參數(shù)方式(也可以直接使用環(huán)境變量進行配置)沛豌,這些操作辦法都屬于靜態(tài)配置。如果在業(yè)務(wù)高峰期赃额,可能需要調(diào)整采樣率 agent.sample_n_per_3_secs 的數(shù)值加派,只能通過重新啟動或者agent方式更新配置信息。
    為了做到通過后臺跳芳,動態(tài)控制agent端的采樣率芍锦、鏈路跨度等配置信息,Skywalking提供了動態(tài)更新功能飞盆。Skywalking支持grpc娄琉、apollo、zookeeper吓歇、etcd孽水、consul、k8s城看、nacos作為動態(tài)更新功能的配置中心女气。詳細配置大家可以去Skywalking官網(wǎng)下載介質(zhì)包進行了解

2.2.2 啟動 OAP Server 和 Web UI

項目采用 standalone模式 + ES7 + nacos配置中心搭建 OAP Server ,配置好application.yml后便可以啟動 OAP Server 和 UI析命。

$ cd apache-skywalking-apm-bin/bin
# 啟動
$ ./startup.sh
SkyWalking OAP started successfully!
SkyWalking Web Application started successfully!

訪問 http://xxxx:8081/ 即可看到如下頁面:


2.3 快速集成

skywalking支持傳統(tǒng)shell和docker模式集成

2.3.1 shell模式

skywalking agent軟件包明細
shell模式需要將agent軟件包拷貝到應(yīng)用部署服務(wù)器主卫,這樣應(yīng)用才能夠使用skywalking agent。

drwxrwxr-x. 2 1001 1002     4096 12月 24 17:13 activations
drwxrwxr-x. 2 1001 1002       85 12月 24 17:13 bootstrap-plugins
drwxrwxr-x. 2 1001 1002       26 12月 24 17:13 config # 配置
drwxrwxr-x. 2 1001 1002        6 7月  30 20:35 logs # 日志
drwxrwxr-x. 2 1001 1002     4096 12月 24 17:13 optional-plugins # 可選插件鹃愤,模式不會運行該目錄下插件簇搅,
如果需要運行,可把對應(yīng)插件拷貝到 /plugins 目錄
drwxrwxr-x. 2 1001 1002       45 12月 24 17:13 optional-reporter-plugins
drwxrwxr-x. 2 1001 1002     8192 12月 24 17:13 plugins # 插件
-rw-rw-r--. 1 1001 1002 19094336 7月  30 20:35 skywalking-agent.jar  

如果應(yīng)用服務(wù)器只部署一個服務(wù)软吐,可以直接修改agent/config目錄下配置瘩将,正常情況不建議這樣做,而是通過設(shè)置系統(tǒng)變量(公共配置)或 啟動命名傳參(私有變量)方式凹耙。更多的變量詳情姿现,可以在[/agent/config/agent.config查看。

java啟動腳本

# 通過系統(tǒng)變量方式設(shè)置 SkyWalking Agent 配置
export SW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800 # 配置 Collector 地址肖抱。
export SW_AGENT_SPAN_LIMIT=300# 配置鏈路的最大 Span 數(shù)量备典。默認為 300 。

# 通過啟動shell命名傳遞SkyWalking Agent 配置
java -javaagent:D:apache-skywalking-apm-es7-8.8.0/apache-skywalking-apm-bin-es7/agentskywalking-agent.jar -Dskywalking.agent.service_name=當前項目在skywalking顯示的名稱 -jar spring-demo-0.0.1-SNAPSHOT.jar

2.3.2 基于docker集成

基于docker集成skywalking agent意述,官方提供了docker鏡像代理提佣,直接在構(gòu)建應(yīng)用服務(wù)鏡像時使用該鏡像代碼作為基礎(chǔ)鏡像構(gòu)建app。

FROM apache/skywalking-java-agent:8.5.0-jdk8

# ... build your java application

不過鏡像代理不是官方版本荤崇,只是為了方便提供拌屏,推薦的方式還是通過源代碼構(gòu)建鏡像。

通過源代碼方式構(gòu)建應(yīng)用鏡像

  • 1. 拷貝/agent 軟件包到應(yīng)用目錄

軟件包和pom.xml在一級目錄术荤,如下圖:

  • 2. 修改軟件包/agent/config/agent.config

這里僅貼出項目實際配置的倚喂,更多詳情見軟件包/agent/config/agent.config

agent.service_name=ds-user-center-server
# Logging file_name
logging.file_name=${SW_LOGGING_FILE_NAME:skywalking-api.log}
# Logging level
logging.level=${SW_LOGGING_LEVEL:WARN}
# 歷史日志文件數(shù)量,這里配置保留一個防止日志文件過多瓣戚,默認-1 不限制
logging.max_history_files=${SW_LOGGING_MAX_HISTORY_FILES:1}

ps:軟件包/agent/config/agent.config配置可以不做任何配置端圈,而是在dockerfile腳本中配置參數(shù)。

  • 3. 添加DockerFile
    這里僅貼出我自己項目的腳本带兜,實際腳本根據(jù)加自己項目調(diào)整
FROM java:8
ADD /app.jar //

# copy arthas
# COPY --from=hengyunabc/arthas:latest /opt/arthas /opt/arthas

COPY agent /usr/local/agent

# 這里可以傳遞skywalking-agent 配置
ENTRYPOINT [ "sh", "-c", "java  -javaagent:/usr/local/agent/skywalking-agent.jar -Dskywalking.agent.service_name=yourappname -Dskywalking.collector.backend_service=xx.xx.xx.xx:11800  -Dspring.profiles.active=dev -jar /app.jar" ]
  • 4. 修改pom.xml打包程序

我們使用的是spotify maven docker插件

<build>
        <finalName>app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.4.3</version>
                <!--加入下面兩項配置-->
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.1.0</version>
                <executions>
                    <execution>
                        <id>build-image</id>
                        <phase>package</phase>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <imageName>${project.artifactId}:${project.version}</imageName>
                    <!--鏡像構(gòu)建成果推送進行到指定存儲庫-->
                    <dockerHost>http://192.168.128.20:2375</dockerHost>
                    <imageTags>
                        <imageTag>latest</imageTag>
                    </imageTags>
                    <!--dockerDirectory 參數(shù)表示使用Dockerfile構(gòu)建鏡像枫笛,${basedir}表示Dockerfile與pom.xml同級目錄 -->
                    <dockerDirectory>${basedir}</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
        </plugins>
    </build>

通過上述步驟構(gòu)建鏡像并運行服務(wù)便可以集成skywalking-agent

整合成果后效果圖-拓撲圖

image.png-拓撲圖

三、 Spring Cloud 微服務(wù)整合skywalking及應(yīng)用實戰(zhàn)

通過上述步驟我們基本能夠?qū)嶋HJava應(yīng)用集成skywalking-agent刚照,下面我們將開始Spring Cloud 微服務(wù)整合skywalking-agent刑巧、微服務(wù)接入skywalking日志、動態(tài)配置无畔、基于skywalking-ui托盤圖進行微服務(wù)調(diào)用關(guān)系分析啊楚、調(diào)用鏈分析、skywalking-agent探針優(yōu)化浑彰、開啟skywalking實戰(zhàn)之旅恭理。

3.1 微服務(wù)整合skywalking-agent

3.1.1 SpringCoud Gateway 集成skywalking-agent

微服務(wù)整合skywalking-agent按照上述Docker集成skywalking-agent步驟便能完成大多數(shù)應(yīng)用的集成,只有SpringCoud Gateway需要進行額外的處理郭变,需要將/optional-plugins可選插件包下apm-spring-cloud-gateway-xx.jar拷貝到/plugins插件包目錄下颜价,具體版本根據(jù)自己微服務(wù)版本而定涯保,本項目使用2.2.4版本,選擇apm-spring-cloud-gateway-2.1.x-plugin-8.7.0.jar即可周伦,不要把所有版本插件全部移動到/plugins

如果SpringCoud Gateway不做上述操作夕春,那么Gateway服務(wù)就和普通服務(wù)一樣,起點就是User专挪,而看不到Gateway作為網(wǎng)關(guān)路由的效果及志。下圖為添加了apm-gateway插件后微服務(wù)全局拓撲圖,可以看到前端訪問微服務(wù)均是通過網(wǎng)關(guān)進行轉(zhuǎn)發(fā):

微服務(wù)拓撲圖

3.1.2 SpringCoud 日志接入skywalking

完成skywalking-agent探針集成后寨腔,我們便可以對微服務(wù)進行調(diào)用鏈和拓撲圖進行分析速侈,但是我們有時還需要通過elk或者其他日志工具對調(diào)用鏈日志進行分析,skywalking提供無侵入式的trace ID迫卢、trace context倚搬、gRPC reporter,支持log4j乾蛤、log4j2潭枣、logback。我們的項目使用logback幻捏,因此這里只介紹logback模式-Print trace ID in your logs盆犁。更多可以查看官方文檔

  • step1 引入skywalking日志組件依賴
        <dependency>
            <groupId>org.apache.skywalking</groupId>
            <artifactId>apm-toolkit-logback-1.x</artifactId>
            <version>8.7.0</version>
        </dependency>
  • step2 修改應(yīng)用日志配置

配置layout,指定class為skywalking TraceIdPatternLogbackLayout篡九,并且在模板中增加tid的錨點谐岁。

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <springProperty scope="context" name="springAppName" source="spring.application.name"/>
    <springProperty scope="context" name="profilesActive" source="spring.profiles.active"/>

    <appender name="consoleApp" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <!--SW layout 配置 -->
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                <Pattern> %date{yyyy-MM-dd HH:mm:ss.SSS} [%tid] %-5level[%thread]%logger{56}.%method:%L -%msg%n</Pattern>
            </layout>
        </encoder>
    </appender>
    <appender name="fileInfoApp" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>DENY</onMatch>
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
            <Pattern> %date{yyyy-MM-dd HH:mm:ss.SSS} [%tid] %-5level[%thread]%logger{56}.%method:%L -%msg%n</Pattern>
        </layout>
        <!-- 滾動策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 路徑 -->
            <fileNamePattern>logs/${springAppName}.info.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <appender name="fileErrorApp" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
            <Pattern> %date{yyyy-MM-dd HH:mm:ss.SSS} [%tid] %-5level[%thread]%logger{56}.%method:%L -%msg%n</Pattern>
        </layout>
        <!-- 設(shè)置滾動策略 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 路徑 -->
            <fileNamePattern>logs/${springAppName}.err.%d.log</fileNamePattern>

            <!-- 控制保留的歸檔文件的最大數(shù)量,超出數(shù)量就刪除舊文件榛臼,假設(shè)設(shè)置每個月滾動伊佃,
            且<maxHistory> 是1,則只保存最近1個月的文件沛善,刪除之前的舊文件 -->
            <MaxHistory>1</MaxHistory>

        </rollingPolicy>
    </appender>
    <springProfile name="dev">
        <root level="INFO">
            <appender-ref ref="consoleApp"/>
            <appender-ref ref="fileInfoApp"/>
            <appender-ref ref="fileErrorApp"/>
        </root>
    </springProfile>
    <springProfile name="test">
        <root level="INFO">
            <appender-ref ref="consoleApp"/>
        </root>
    </springProfile>
    <springProfile name="prod">
        <root level="INFO">
            <appender-ref ref="consoleApp"/>
        </root>
    </springProfile>
</configuration>

修改完配置航揉,啟動應(yīng)用,可以看到如下效果:當應(yīng)用激活了SW agent金刁,外部請求日志打印會攜帶tid帅涂,而內(nèi)部請求則打印N/A。

2022-02-07 00:00:00.031 [TID:N/A] INFO [xxl-rpc, EmbedServer bizThreadPool-71423529]com.xxl.job.core.executor.XxlJobExecutor.registJobThread:159 ->>>>>>>>>>> xxl-job regist JobThread success, jobId:144, handler:com.xxl.job.core.handler.impl.MethodJobHandler@c8567c9[class com.xxxx.saas.dsuserserver.job.VipActivePackagesExpiredStateJob$$EnhancerBySpringCGLIB$$72fe4b40#vipActivePackagesExpiredState]
2022-02-07 00:00:00.036 [TID:3344006a6a504161b199c17d5778a36d.3192.16441632000360001] INFO [Thread-1559]c.m.s.dsuserserver.job.VipActivePackagesExpiredStateJob.vipActivePackagesExpiredState:42 -================vipActivePackagesExpiredState start:1644163200036================
2022-02-07 00:00:00.112 [TID:3344006a6a504161b199c17d5778a36d.3192.16441632000360001] INFO [Thread-1559]c.m.s.dsuserserver.job.VipActivePackagesExpiredStateJob.vipActivePackagesExpiredState:46 -================vipActivePackagesExpiredState end:1644163200112================
2022-02-07 00:01:33.130 [TID:N/A] INFO [Thread-1559]com.xxl.job.core.thread.JobThread.run:212 ->>>>>>>>>>> xxl-job JobThread stoped, hashCode:Thread[Thread-1559,10,main]
2022-02-07 10:34:52.757 [TID:d9bb5cb491e34b5ca945c591a326ed8b.69.16442012921820337] INFO [http-nio-7004-exec-8]c.d.saas.common.feign.interceptor.MyOkhttpInterceptor.intercept:23 -OkHttp Feign 發(fā)送請求 [http://192.168.128.20:7001/oauth/token?password=a123456&grant_type=password&userType=1&username=sujingjun%40dhgate.com] on [null]

使用日志追蹤打印的tid尤蛮,在SW UI 追蹤模塊可以追蹤到對應(yīng)的請求鏈路媳友,如下圖:


image.png

源碼分析

  • TraceIdPatternLogbackLayout:TraceIdPatternLogbackLayout繼承ch.qos.logback.classic.PatternLayout,添加了LogbackPatternConverter和LogbackSkyWalkingContextPatternConverter轉(zhuǎn)換器产捞,支持%tid占位符醇锚。
ublic class TraceIdPatternLogbackLayout extends PatternLayout {
    public TraceIdPatternLogbackLayout() {
    }

    static {
        defaultConverterMap.put("tid", LogbackPatternConverter.class.getName());
        defaultConverterMap.put("sw_ctx", LogbackSkyWalkingContextPatternConverter.class.getName());
    }
}
// 這里實際僅是一個入口程序,實際日志打印實現(xiàn)是agent-activation包下定義的切面和攔截器處理
public class LogbackPatternConverter extends ClassicConverter {
    public LogbackPatternConverter() {
    }

    public String convert(ILoggingEvent iLoggingEvent) {
        return "TID: N/A";
    }
}

public class LogbackPatternConverterActivation extends ClassInstanceMethodsEnhancePluginDefine {

    public static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.toolkit.activation.log.logback.v1.x.PrintTraceIdInterceptor";
    public static final String ENHANCE_CLASS = "org.apache.skywalking.apm.toolkit.log.logback.v1.x.LogbackPatternConverter";
    public static final String ENHANCE_METHOD = "convert";

    /**
     * @return the target class, which needs active.
     */
    @Override
    protected ClassMatch enhanceClass() {
        return byName(ENHANCE_CLASS);
    }

    /**
     * @return null, no need to intercept constructor of enhance class.
     */
    @Override
    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
        return null;
    }

    /**
     * @return the collection of {@link StaticMethodsInterceptPoint}, represent the intercepted methods and their
     * interceptors.
     */
    @Override
    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
        return new InstanceMethodsInterceptPoint[] {
            new InstanceMethodsInterceptPoint() {
                @Override
                public ElementMatcher<MethodDescription> getMethodsMatcher() {
                    return named(ENHANCE_METHOD).and(takesArgumentWithType(0, "ch.qos.logback.classic.spi.ILoggingEvent"));
                }

                @Override
                public String getMethodsInterceptor() {
                    return INTERCEPT_CLASS;
                }

                @Override
                public boolean isOverrideArgs() {
                    return false;
                }
            }
        };
    }
}
  • PrintTraceIdInterceptor: PrintTraceIdInterceptor是%tid占位符轉(zhuǎn)換的實際處理攔截器焊唬,*.afterMethod() 方法調(diào)用 ContextManager#getGlobalTraceId() 方法恋昼,使用全局鏈路追蹤編號。
public class PrintTraceIdInterceptor implements InstanceMethodsAroundInterceptor {

    @Override
    public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        MethodInterceptResult result) throws Throwable {

    }

    @Override
    public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        Object ret) throws Throwable {
        if (!ContextManager.isActive()) {
            if (allArguments[0] instanceof EnhancedInstance) {
                SkyWalkingContext skyWalkingContext = (SkyWalkingContext) ((EnhancedInstance) allArguments[0]).getSkyWalkingDynamicField();
                if (skyWalkingContext != null) {
                    return "TID:" + skyWalkingContext.getTraceId();
                }
            }
        }
        return "TID:" + ContextManager.getGlobalTraceId();
    }

    @Override
    public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
        Class<?>[] argumentsTypes, Throwable t) {

    }
}

更多源碼詳情參考官方https://github.com/apache/skywalking


3.1.3 忽略追蹤某項節(jié)點url

SW支持忽略特點節(jié)點url赶促,要支持節(jié)點忽略功能需要將apm-trace-ignore-plugin-8.7.0.jar插件包拷貝到../plugins目錄下焰雕,同時需要在../config目錄下增加配置文件apm-trace-ignore-plugin.config,并加入trace.ignore_path=${SW_AGENT_TRACE_IGNORE_PATH:/api-docs/**} 為例芳杏,來忽略請求url的追蹤,示例如下:

trace.ignore_path=/api-docs/**,/actuator/**

3.2 客戶端動態(tài)配置

按照Skywalking官網(wǎng)的客戶端搭建方式辟宗,基本采取配置文件爵赵,或者通過java -D 帶參數(shù)方式(也可以直接使用環(huán)境變量進行配置),這些操作辦法都屬于靜態(tài)配置泊脐。如果在生產(chǎn)環(huán)境需要調(diào)整采樣率空幻、忽略url等,只能通過重新啟動agent方式更新配置信息容客。

Skywalking官方提供了動態(tài)更新功能秕铛,可以結(jié)合配置中心實現(xiàn)后臺動態(tài)更新agent采樣率、忽略url缩挑、調(diào)用鏈深度等配置但两。

3.2.1 動態(tài)配置說明

SW 支持以下動態(tài)配置:

配置key 參數(shù)描述 參數(shù)示例
agent-analyzer.default.slowDBAccessThreshold 慢sql的閾值,覆蓋application.yml中receiver-trace/default/slowDBAccessThreshold default:200,mongodb:50
agent-analyzer.default.uninstrumentedGateways 網(wǎng)關(guān)配置 參數(shù)參考gateways.yml
alarm.default.alarm-settings 告警配置 參考alarm-settings.yml
core.default.endpoint-name-grouping 端點分組配置 參考service-apdex-threshold.yml
core.default.log4j-xml log4j配置 參考log4j2.xml
configuration-discovery.default.agentConfigurations ConfigurationDiscovery 配置 參考configuration-discovery.md

更多動態(tài)配置說明參考Dynamic Configuration

3.2.2 集成nacos實現(xiàn)SW動態(tài)配置

SW動態(tài)配置依賴上游配置服務(wù)供置,因此默認是關(guān)閉的谨湘,在2.2 核心配置已經(jīng)介紹過配置中心配置說明,這里不再贅述芥丧。我們直接從nacos集成步驟開始

  • step1 nacos配置中心安裝部署

我們直接使用SpringCloud nacos配置中心作為SW配置中心不再額外部署nacos紧阔,nacos安裝部署可以參考官方https://nacos.io/zh-cn/docs/deployment.html

  • 修改OAP Server

修改OAP Server application.yml 開啟動態(tài)配置并使用nacos作為配置中心


configuration:
  selector: nacos #開啟開啟動態(tài)配置并使用nacos作為配置中心
  nacos:
    # Nacos Server Host
    serverAddr: ${SW_CONFIG_NACOS_SERVER_ADDR:192.168.128.20}
    # Nacos Server Port
    port: ${SW_CONFIG_NACOS_SERVER_PORT:8848}
    # Nacos Configuration Group
    group: ${SW_CONFIG_NACOS_SERVER_GROUP:skywalking}
    # Nacos Configuration namespace
    namespace: ${SW_CONFIG_NACOS_SERVER_NAMESPACE:1c53b59e-9f3d-44a4-b2d7-5faaea25b3c6}
    # Unit seconds, sync period. Default fetch every 60 seconds.
    period: ${SW_CONFIG_NACOS_PERIOD:60}
    # Nacos auth username
    username: ${SW_CONFIG_NACOS_USERNAME:""}
    password: ${SW_CONFIG_NACOS_PASSWORD:""}
    # Nacos auth accessKey
    accessKey: ${SW_CONFIG_NACOS_ACCESSKEY:""}
    secretKey: ${SW_CONFIG_NACOS_SECRETKEY:""}

nacos動態(tài)配置結(jié)果如下:

nacos動態(tài)配置
nacos動態(tài)配置

3.2.3 ConfigurationDiscovery 配置舉例說明

ConfigurationDiscovery 配置了服務(wù)發(fā)現(xiàn)配置,包含采樣率续担、不記錄鏈路信息url后綴擅耽、不記錄鏈路信息url、鏈路最大跨度物遇。ConfigurationDiscovery 配置示例如下:

configurations:
    ds-user-center-server: 
        agent.trace.ignore_path: Mysql/**,Lettuce/**,/941124188381/*,Lettuce/EXISTS/**,MongoDB/**
    uaa-center-server: 
        agent.trace.ignore_path: /api-docs/**,/actuator/**,Mysql/**,Lettuce/**,Lettuce/EXISTS/**
    gateway-server: 
        agent.trace.ignore_path: /api-docs/**,/actuator/**

ConfigurationDiscovery 配置模板

ConfigurationDiscovery 按服務(wù)維度進行配置

configurations:
  //service name
  serviceA:
    // Configurations of service A
    // Key and Value are determined by the agent side.
    // Check the agent setup doc for all available configurations.
    key1: value1
    key2: value2
    ...
  serviceB:
    ...

ConfigurationDiscovery 配置說明

key 參數(shù)描述 參數(shù)示例 依賴插件
agent.sample_n_per_3_secs 每3秒采集鏈路數(shù)據(jù),-1表示全部收集 -1 -
agent.ignore_suffix 不記錄鏈路信息url后綴(第一個節(jié)點開始算起)乖仇,如果多個,采用逗號,隔開 .txt,.log -
agent.trace.ignore_path 記錄調(diào)用鏈的路徑询兴,多個可以采用逗號,隔開 /your/path/1/,/your/path/2/ apm-trace-ignore-plugin
agent.span_limit_per_segment 鏈路最大跨度 300 -

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末这敬,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蕉朵,更是在濱河造成了極大的恐慌崔涂,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件始衅,死亡現(xiàn)場離奇詭異冷蚂,居然都是意外死亡缭保,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來齐婴,“玉大人唐瀑,你說我怎么就攤上這事∏。” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵蹄衷,是天一觀的道長忧额。 經(jīng)常有香客問我,道長愧口,這世上最難降的妖魔是什么睦番? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮耍属,結(jié)果婚禮上托嚣,老公的妹妹穿的比我還像新娘。我一直安慰自己厚骗,他們只是感情好示启,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著领舰,像睡著了一般丑搔。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上提揍,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天啤月,我揣著相機與錄音,去河邊找鬼劳跃。 笑死谎仲,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的刨仑。 我是一名探鬼主播郑诺,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼杉武!你這毒婦竟也來了辙诞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤飞涂,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體士八,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡官卡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了仔涩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡粘舟,死狀恐怖熔脂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情柑肴,我是刑警寧澤霞揉,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站晰骑,受9級特大地震影響适秩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜硕舆,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一秽荞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抚官,春花似錦扬跋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至倍奢,卻和暖如春朴上,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背卒煞。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工痪宰, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓酵镜,卻偏偏與公主長得像碉碉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子淮韭,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容