Hi~朋友,关注置顶防止错过消息
为什么需要链路追踪
随着应用的增多,各个应用之间的调用关系也错综复杂,在多应用之间排查问题的代价也越来越高,任何一个系统的异常都有可能影响到其他系统,为了快速定位问题和发现问题,我们需要将所有应用的调用链进行可视化,以一个直观的方式展示系统之间的调用关系以及各个接口的响应时间。
随着现在监控系统的日趋完善,很多大公司都已经有了可观测性系统,而链路追踪可能只是很小的一部分,但却很重要,因为这可以帮助开发很轻易的定位到底哪个环节出了问题。
链路追踪系统的选型
目前市面上开源的链路追踪系统还是比较多的,主要有以下几种:
我们当时在选型链路追踪系统的时候主要根据以下标准:
依据公司现有的架构和上述标准,我们最终选择了skywalking作为我们的链路系统,选型的时候我们是尽可能技术栈统一,简单易用,避免技术栈异构给整个架构带来的不稳定。
现有的基础设施
关于对接的步骤
第一阶段
第二阶段
应用如何对接
我们需要对k8s的Deployment配置文件进行改造,需要将Agent挂载进我们的容器,以便启动的时候我们的Java应用程序可以加载到Agent,在这里我们是通过init容器的方式来实现:
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: application-test
name: xxxx
labels:
app: xxxx
spec:
replicas: 2
selector:
matchLabels:
app: xxxx
strategy:
...
template:
metadata:
labels:
app: xxxx
spec:
restartPolicy: Always
volumes:
- name: skywalking-agent
emptyDir: { }
initContainers:
- name: skywalking-agent
image: xxxxx:java-agent-8.14.0-alpine
volumeMounts:
- name: skywalking-agent
mountPath: /skywalking-agent
command: [ "/bin/sh"]
args: [ "-c", "cp -R /skywalking/agent /skywalking-agent/; cp /skywalking-agent/agent/optional-plugins/apm-trace-ignore-plugin-8.14.0.jar /skywalking-agent/agent/plugins/"]
containers:
- name: xxxx
image: DEPLOY_IMAGE
...
volumeMounts:
- name: skywalking-agent
mountPath: /skywalking-agent
envFrom:
- configMapRef:
name: xxxxx
envFrom.configMapRef.name:指定了我们环境变量的ConfigMap,在该ConfigMap中有几个环境变量需要我们去定义:
上述配置没问题以后,当我们完成Deployments部署以后,在我们的 Pod中可以看到init容器和应用容器都被正常运行,而且在 Skywalking的UI页面上看到我们的Service。
如何将traceId对接进日志
maven
<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-logback-1.x</artifactId>
<version>8.14.0</version>
</dependency>
gradle
implementation("org.apache.skywalking:apm-toolkit-logback-1.x:8.14.0")
2. 改造你的logback配置文件
<?xml version="1.0" encoding="UTF-8"?>
<configurationscan="true"scanPeriod="30 seconds">
<propertyname="JSON_LOG_PATTERN"
value='{
"timestamp": "%d{yyyy-MM-dd HH:mm:ss.SSS}",
"traceId": "%tid",
"skyWalkingContext": "%sw_ctx",
"thread": "%t",
"level": "%level",
"class": "%logger",
"content": "%msg",
"exception": "%exception"
}'/>
<!-- add converter for %tid -->
<conversionRuleconversionWord="tid"converterClass="org.apache.skywalking.apm.toolkit.log.logback.v1.x.LogbackPatternConverter"/>
<!-- add converter for %sw_ctx -->
<conversionRuleconversionWord="sw_ctx"converterClass="org.apache.skywalking.apm.toolkit.log.logback.v1.x.LogbackSkyWalkingContextPatternConverter"/>
<springProfilename="local,test,prod">
<appendername="console"class="ch.qos.logback.core.ConsoleAppender">
<encoderclass="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
<providers>
<pattern>
<pattern>
${JSON_LOG_PATTERN}
</pattern>
</pattern>
</providers>
</encoder>
</appender>
<rootlevel="INFO">
<appender-refref="console"/>
</root>
</springProfile>
</configuration>
日志在改造完成以后,重新部署以后我们就可以看到traceId和skyWalkingContext,如下图:
我们拿着traceId去查Skywalking页面上可以看到整个请求链路(如下图),同样的我们在Skywalking页面上拿到的traceId也可以去日志系统中拉取到所有的日志。
总结
当系统随着业务的发展变得错综复杂时,我们则需要借助一些工具来可视化我们的整个系统,作为开发我们需要学会"偷懒",学会利用工具来帮我们减少定位问题的时间,学会利用工具梳理我们系统中还不完善的点去改进优化它,帮助系统跑的更快更稳。