链路追踪

在微服务架构下,服务间调用是很平常的事件,经常存在多个服务间的相互调用,每一次完整的请求都有可能经过好几个微服务的处理,当服务多起来之后,服务间的调用关系就很难理清。

在这里插入图片描述

微服务链路追踪的作用主要是跟踪记录每一次请求的完整调用链路,也就是记录一次请求都经过了哪些微服务。链路追踪的主要思想如下:

在这里插入图片描述

  1. 一般通过javaagent、拦截器、代码侵入等方式收集调用链经过的每个微服务的接口信息,发送到链路追踪服务端。
  2. 链路追踪保存收集到的链路追踪数据,一般会记录是哪个服务的,以及traceId(整个调用链唯一)、spanId等。数据可以保存到数据库、ES或其他存储载体中。
  3. 然后链路追踪的UI界面查询链路追踪服务,链路追踪服务从存储链路追踪数据的地方查询返回链路追踪信息,然后UI界面展示整个调用链路信息。

链路追踪几种解决方案:

  • SkyWalking
  • Pinpoint
  • Sleuth + Zipkin
  • CAT

下面对以上几种方案进行逐一的介绍。

SkyWalking

SkyWalking是国内开源的链路追踪框架,特点是可以通过字节码注入技术实现代码的零侵入,并且对服务的性能损耗较小。

SkyWalking 架构

在这里插入图片描述

SkyWalking分为代理端和服务端。

代理端通过javaagent进行字节码增强,拦截指定的接口或方法,收集追踪信息(trace)。也可以通过Service Mesh服务网格收集监控指标数据。还可以通过SkyWalking提供的SDK以代码侵入的方式收集追踪数据,但是这种方式一般很少使用。

代理端收集到的数据会通过http或grpc发送到服务端(SkyWalking OAP),服务端接收到数据后会进行数据分析,然后写入到存储(Storage)中,目前支持的数据存储包括ES、MySQL、H2等等。

然后SkyWalking UI界面或者CLI命令行工具可以请求SkyWalking服务端查询链路追踪信息,服务端从数据存储中查询数据返回。

SkyWalking 部署搭建与使用

要部署SkyWalking,首先需要下载SkyWalking服务端的包还有agent包。

在这里插入图片描述

下载并解压后,可以通过修改config/application.yml配置文件对服务端进行配置,可以修改使用的数据存储,默认是H2,可以修改为MySQL或ES等。

在这里插入图片描述

然后运行bin/startup.sh命令启动服务端,会启动skywalking-oap-server和skywalking-web-ui两个服务,skywalking-oap-server会暴露11800和12800两个端口(可修改),11800用于收集数据,12800用于接受前端请求。而skywalking-web-ui会暴露8080端口(可修改)。

在这里插入图片描述

然后我们启动微服务时,只要加上-javaagent参数指定SkyWalking的代理jar包即可:

java ‐javaagent:/root/skywalking‐agent/skywalking‐agent.jar
‐DSW_AGENT_COLLECTOR_BACKEND_SERVICES=127.0.0.1:11800
‐DSW_AGENT_NAME=skywalking‐demo ‐jar skywalking‐demo‐0.0.1‐S
NAPSHOT.jar

在这里插入图片描述

如果要让SkyWalking收集日志信息并展示的话,微服务要引入一个apm‐toolkit‐logback‐1.x的maven依赖包。

<dependency>
	<groupId>org.apache.skywalking</groupId>
	<artifactId>apm‐toolkit‐logback‐1.x</artifactId>
	<version>8.11.0</version>
</dependency>

然后在logback-spring.xml配置文件中配置skywalking的Appender。

<appender name="grpc‐log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.
x.log.GRPCLogClientAppender">
	<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
		<layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternL
		ogbackLayout">
			<Pattern>%d{yyyy‐MM‐dd HH:mm:ss.SSS} [%tid] [%thread] %‐5level %logger{36} ‐
			%msg%n</Pattern>
		</layout>
	</encoder>
</appender>

在这里插入图片描述

Pinpoint

Pinpoint是韩国人开源的基于字节码增加技术的链路追踪框架。Pinpoint和SkyWalking一样通过javaagent进行字节码注入,实现代码零侵入,但是相较于SkyWalking对服务的性能损耗较高。

Pinpoint 架构

在这里插入图片描述

Pinpoint的架构和SkyWalking也类似,一个Agent代理端,一个Controller服务端,还有一个UI界面。
服务端将接收到的数据存入HBase中。

Pinpoint 搭建部署与使用

Pinpoint的搭建使用步骤也和SkyWalking很相似。

首先在github下载服务端的包pinpoint-docker,然后启动。

在这里插入图片描述

然后下载代理端的包,在启动微服务时通过-javaagent参数指定Pinpoint的代理包。

java ‐javaagent:${pinpointPath}/pinpoint‐bootstrap‐1.8.5.jar
‐Dpinpoint.applicationName=order‐service
‐Dpinpoint.agentId=order‐service
-jar order-sevice.jar

假如我们通过ELK进行日志收集,我们可以在日志中加入Pinpoint打印的transaction id(整个调用链唯一),来实现日志追踪。

在这里插入图片描述

只要在入pinpoint-agent目录,修改配置文件pinpoint.config里的配置profiler.logback.logging.transactioninfo的值为true,这样pinpoint-agent就会把transaction id写入logback日志,然后我们在件logback-spring.xml,加入PtxId(就是transaction id)即可。

<!‐‐输出到logstash的appender‐‐>
<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
	<!‐‐可以访问的logstash日志收集端口‐‐>
	<destination>172.17.0.1:4560</destination>
	<encoder>
		<pattern>%d{yyyy‐MM‐dd HH:mm:ss.SSS} [%X{PtxId}] [%thread] %‐5level %logger{50} ‐ %msg%n</pattern>
		<charset>UTF‐8</charset>
	</encoder>
</appender>

在这里插入图片描述
在这里插入图片描述

Sleuth + Zipkin

Sleuth + Zipkin这种方案,就是通过Spring-Cloud-Sleuth进行链路追踪信息的收集,然后发送到Zipkin进行存储,最后通过Zipkin提供的UI界面进行查询。

在这里插入图片描述

Sleuth通过过滤器记录TraceId和SpanID,然后通过http或者消息中间件把记录的链路最终信息发送到Zipkin服务端,服务端存储该信息,然后Zipkin提供一个UI界面可用调用Zipkin服务端的接口查询链路追踪信息。

在这里插入图片描述

而Zipkin服务端端内部,通过Controller接收外部发送过来的跟踪信息,然后调用Storage存储组件保存数据。而Zipkin的UI界面会调用Zipkin的Restful API接口查询跟踪信息。

CAT

CAT是大众点评开源的基于SDK以代码侵入的方式打点进行链路追踪信息收集的开源框架,由于是代码侵入的方式,用的就更少了,因此就不作介绍。

各方案对比

首先CAT是代码侵入的,因此直接pass掉。

然后Sleuth+Zipkin已经是比较老旧的解决方案,如果是老系统,已经使用了这种方案进行链路追踪的话,那可用继续使用。

而Pinpoint和SkyWalking都是对代码无侵入的,但是Pinpoint对服务的性能影响比SKyWalking高,因此还是首推SKyWalking。

更多推荐