Spring Cloud Sleuth

Spring Cloud Sleuth

Spring CloudSleuth为微服务之间调用提供了一套完整的服务链路跟踪解决方案可以帮助开发者做以下几件事
.耗时分析:通过Sleuth 可以很方便地了解到每个来样请求的耗时,从而分析出哪些
微服务调用比较耗时。

·可视化错误:对于程序未捕捉的异常,可以在集成Zipkin 服务界面上看到。

.链路优化:通过Sleuth 可以轻松识别出调用比较频繁的微服务,开发者可以针对这
些微服务实施相应的优化措施。

Sleuth 的实现原理

.服务追踪:对于同一个用户请求,认为是同一条链路,井赋值一个相同的TraceID,
在后续中通过该标识就可以在多个微服务之间找到完整的处理链路。

.服务监控:对于链路上的每一个微服务处理, Sleuth 会再生成一个独立的SpanID,
同时记录请求到达时间和离开时间等信息,以作为用户请求追踪的依据,从而判断
每一个微服务的处理效率。

Sleuth 所涉及的一些主要术语

• Span :是Sleuth 中最基本的工作单元。微服务发起一次请求就是一个新Span 。Span使用唯一的、长度为64 位的ID 作为标识。在Span 中可以带有其他数据,如描述、时间戳、键值对、起始Span 的ID 等数据。Span 有起始和结束,可以用于跟踪服务处理时间信息。Span 一般都是成对出现,因为有始必有终,所以一旦创建了一个Span ,就必须在未来某个时间点结束它。

• Trace : 一次用户请求所涉及的所有Span 的集合,采用树形结构进行管理。

• Annotation :用于记录时间信息,包含了以下几项。

cs : 客户端发送( Client Sent ), 表示一个Span 的起始点。
sr :服务端接收( Server Received ), 表示服务端接收到请求并开始处理。
如果减去cs 的时间戳,则可以计算出网络传输耗时。
ss :服务端完成请求处理,应答信息被发回客户端( Server Sent ) 。通过减
去sr 的时间戳,可以计算出服务端处理请求的耗时。
er :客户端接收( C lient Received ),标志着一个Span 生命周期的结束, 客
户端成功地接收到服务端的应答信息。如果减去cs 的时间戳,则可以计算
出整个请求的响应耗时。

在这里插入图片描述

启动测试

在pom .xml 文件中增加对spring-cloud-starter-sleuth 的依赖,增加的脚本代码
如下:
< dependency>
< groupid>org.springframework . cloud< /groupid>
< artifactid>spring - cloud - starter - sleuth< /artifactid>
< /dependency>
启动相关服务 这时在ProductService 控制台中可 以看到类似下面的日志输出:

【 2017 - 11 - 28 19: 01 : 43. 589】DEBUG [productservice , 826bfe5c0116e8f3 , 826bfe5c011
6e8f3 , false] 20287 — [nio-2200 - exec- 5] o.s . web.servlet.DispatcherServlet :

我们可以看到该日志的每一条信息中都包含这样一条数据:[ prod uctservice,826bfe
5c01l6e8f3 , 826bfe5c0116e8f3,false ],这就是Sleuth 所生成的追踪数据,它们的格式为
[ App li cationN ame, Traceld,S panld ,Exportab l e ] ,该数据包含了下面4 种信息。

• ApplicationName :这里的值为productserv i ce , 是Sier由当前所追踪服务的服务名
称,也就是前面在bootstrap. properties 文件的配置。需要注意, 该值必须在
bootstrap.properties 文件中进行配置,这是由于日志框架启动时间较早造成的。如
果是在application.properties 文件中进行配置,则会因为该配置数据尚未加载而导致
日志框架无法获取到该值。

• Traceld : 这里的值为826 bfe5c0 l l 6e8 日, 对应于客户端的每次请求, 也就是一次请
求处理的链路。通过该标识符就可以找到一次客户端请求完整的处理链路。

• Spanld :这里的值为82 6bfe5c0 l l 6e8 日,对应于每次请求中每一个处理部分, 也就
是该请求链路中的每一环, 是Sleuth 追踪的最基础工作单元。一次链路请求最起始
的Span 通常被称为根S pan ( Root Span ),它的ID 通常也被作为Trace 的ID ,因
此在这里Traceld 和Spanld 的值是一样的。

• Exportable : 是否将追踪到的信息输出到Zipkin 服务器等日志采集服务器上。

tracer span

新增span

@Autow ired
private Tracer tracer;
Span mySpan = this . tracer . createSpan (川nySpanName ’” ) ;
//我们也可以在追踪数据中添加一些自定义数据
this.tracer.addTag (” myTag ”, myTag) ;
//一定要记得关闭,否则所采集的数据不会发送给采集器
this .t racer . close(mySpan );

@NewSpan
void createMySpan() ;
@NewSpan ( ” cd826TestSpan ”)
void createMySpan() ;
@NewSpan
void createMySpan(@SpanTag ( ” myTag ”) String myTagParam) ;

关闭一个Span

关闭Span 时Sleuth 才会根据配置将来集到的数据通过spanReporter 发送采集器
当使用Tracer 创建自己的Span 时, 一定要记住最后使用c l ose()方法将其关闭, 否则Sleuth
是不会将采集到的数据发送给采集服务器的(如Zipkin ) 。

继续使用一个Span

当调用Tracer 的continueSpan ()方法创建Span 时,其实只是原Span 的一个备份。
Sleuth 也提供了相应的注解自ContinueSpan ,示例如下:

@ContinueSpan
void myContinueSpan(@SpanTag (”myContinue’rag ”) String tagParam) ;

相对于createSpan()所创建的Span ,需要在使用完毕之后使用close ()方法将Span 关闭,
continueSpan ()所生成的Span ,需要在使用完毕之后使用detach ()方法将Span 从当前线程中移
除。从Tracer 的源码中可以看到detach()方法只是调用SpanContextHo lder.removeCurrentSpan()
方法从上下文中移除,并没有将Span 所采集到的数据发送给采集器。

Span 命名

默认情况下S leuth 将使用方法的名称或者类的名称简称作为Span的名称
Sleuth 也提供了注解的方式设定Span 的名称,长度小于的50 个字符。过多会调用SpanNameUtil.shorten ()方法对名称进行裁,例如:

@SpanName ( ” cd826RunnableSpan ")
class ProductRatingRunnable implements Runnable

Sleuth 与ELK 整合

每一个微服务实例所产生的日志被分散地储存不同的设备上,需要在基于微服务架构的应用中引入集中化日志管理,如ELK ,集中对所有微服务所产生的日志进行查询分析等处理。

ELK 解决方案其实由3 个开源工具组成,分别是Elasticsearch 、Logstash 和Kiabana 。

• Elasticsearch : 承担存储和分析功能,其具有分布式、零配置、自动发现、索引自动
分片、副本机制及自动搜索负载等特点,同时提供Restfu l 风格接口供开发者使用。

• Logstash :负责收集数据和进行简单数据处理,并将采集的数据输出给ElasticSearch 。
通过Logstash 我们可以采集各微服务实例所生成的日志。

• Kibana:负责将Logstash 所采集的日志,利用Elasticsearch 进行搜索分析,通过友
好的可视化界面, 提供日志的可视化分析、搜索和报表统计等功能。

引入依赖:

< dependency>
< groupid>net.logstash.logback< /groupid>
< artifactid>logstash-logback- encoder< /artifactid>
< version>4.11< /version >
< /dependency>
然后需要对日志配置文件进行修改
增加一个名称为logstash 的Appender 。在配置中指定了Logstash 服务器地址192.168 . 199.212 : 9260 及日志输出的编码器。

〈!一Logstash 日志Appender 一〉
< appender name= ” logstash ” class =” net.logstash.logback.appender.LogstashTcpSocketAppender ” >
----- < param name= ”Encoding ” value=” UTF - 8 ” />
----- 〈! 一配置Logstash 服务器的地址一〉
----- < remoteHost>192 .16 8 . 199 . 212< /remoteHost>
----- < port>9260< /port>
----- 〈! 一通过日志编码器,将日志转换成JSON 字符串一〉
----- < encoder class= ’”net.logstash.logback.encoder.LogstashEncoder " />
< /appender>

Logstash 与Log4j 的集成
使用的日志不是Logback 而是Log4j
日志配置文件中配置如下:
< appender name =” socketAppender ” class = ” org.apache.log4j.net.SocketAppender " >
< param name=” remoteHost ” value=” 192.168.199.212” / >
< param name=”port ” value=” 9260 ” />
< param name=” Threshold" value=” INFO " />
< param name=” ReconnectionDelay" value=”1000 ” / >
< param 口ame = ” Locationinfo” value= ” true" />
< /appender>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值