链路跟踪,咱们有不少可选项。常见的有 zipkin,pinpoint,skywalking,jaeger 等。git
基本上都是根据谷歌的《Dapper 大规模分布式系统的跟踪系统》这篇论文发展出来的。github
今天讲下 Cat 里的链路跟踪要如何来实现,没用过 Cat 的同窗能够查看个人这篇文章 《熬夜之做:一文带你了解 Cat 分布式监控》进行了解。数据库
在 Cat 中能够很方便的看到每一个请求的总耗时以及业务操做,数据库操做的耗时状况。对于服务之间的调用也能够经过埋点的方式进行监控。微信
以下图,能够看出请求内发起了一次 RPC 的调用,callRPC 开头的那条记录。耗时 11ms, 可是这个 RPC 服务内部耗时花在哪里了,在这边不能直接查看,只能去另外一个服务中查看,不是很方便。app
图片
详细的我画了一张图说明下如今的问题:分布式
从上图能够看出,一个请求通过了多个服务,每一个服务中对远程调用或者本地调用都有埋点,这样就能监控到调用的异常和性能指标。ide
下面一部分是在 Cat 中咱们去查看这些指标的场景,Cat 中的数据展现是以项目维度来展现的,因此每一个服务都有本身的监控数据。微服务
若是我想要知道刚刚那次请求,在整个链路中哪里最慢,耗时在哪里,我得分别去 4 个服务下面才能看到这些信息,不直观。性能
以下图所示:学习
从网关到服务,从服务到服务,都须要将 Trace 信息进行传递才能够将整个链路串起来。只有串起来了才能够在 Cat 中查看到整个链路的耗时信息。
本文须要实现的效果就是能够在请求的入口处(网关),查看到这个请求通过的全部服务,每一个服务中的耗时状况。
要想将整个请求都串连起来,必需要有一个惟一的请求标识,通常咱们称之为 traceId。剩余的工做就是将链路相关的信息层层传递下去。
首先在每一个服务的过滤器中进行请求头信息的接收,好比从网关到服务 A,那么服务 A 须要接收这些信息而后传递给下一个服务。
HTTP 请求的消息树构建:
// 构建远程消息树 if(request.getHeader(CatConstantsExt.CAT_HTTP_HEADER_ROOT_MESSAGE_ID) != null){ CatContext catContext = new CatContext(); catContext.addProperty(Cat.Context.ROOT,request.getHeader(CatConstantsExt.CAT_HTTP_HEADER_ROOT_MESSAGE_ID)); catContext.addProperty(Cat.Context.PARENT,request.getHeader(CatConstantsExt.CAT_HTTP_HEADER_PARENT_MESSAGE_ID)); catContext.addProperty(Cat.Context.CHILD,request.getHeader(CatConstantsExt.CAT_HTTP_HEADER_CHILD_MESSAGE_ID)); Cat.logRemoteCallServer(catContext); }
将消息树的信息传递给下个服务的话就要看你用的调用方式是什么,若是用 Feign 或者 RestTemplate 均可以利用拦截器来实现传递。
public class FeignRequestInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { CatContext catContext = new CatContext(); Cat.logRemoteCallClient(catContext,Cat.getManager().getDomain()); template.header(CatConstantsExt.CAT_HTTP_HEADER_ROOT_MESSAGE_ID, catContext.getProperty(Cat.Context.ROOT)); template.header(CatConstantsExt.CAT_HTTP_HEADER_PARENT_MESSAGE_ID, catContext.getProperty(Cat.Context.PARENT)); template.header(CatConstantsExt.CAT_HTTP_HEADER_CHILD_MESSAGE_ID, catContext.getProperty(Cat.Context.CHILD)); } } 若是用的是 D ```ubbo 的话能够用 Dubbo 的 Filter 来实现相同的效果。 最终的效果以下图,调用了 articles/newest 接口,网关将请求转发到 article-provider 服务,article-provider 中又调用了 user-provider 的 users/uid 接口获取用户信息,最重要的是 user-provider 中有哪些操做的耗时在这里也能直观的看到,很是方便。  完整源码参考:https://github.com/yinjihuan/kitty[1] 关于做者 :尹吉欢,简单的技术爱好者,《Spring Cloud 微服务-全栈技术与案例解析》, 《Spring Cloud 微服务 入门 实战与进阶》做者, 公众号 猿天地 发起人。我的微信 jihuan900 ,欢迎勾搭。 后台回复 学习资料 领取学习视频 