谁说Cat不能做链路跟踪的,给我站出来

背景

链路跟踪,我们有很多可选项。常见的有 zipkin,pinpoint,skywalking,jaeger 等。

基本上都是根据谷歌的《Dapper 大规模分布式系统的跟踪系统》这篇论文发展出来的。

今天讲下 Cat 里的链路跟踪要如何来实现,没用过 Cat 的同学可以查看我的这篇文章 《熬夜之作:一文带你了解 Cat 分布式监控》进行了解。

在 Cat 中可以很方便的看到每个请求的总耗时以及业务操作,数据库操作的耗时情况。对于服务之间的调用也可以通过埋点的方式进行监控。

如下图,可以看出请求内发起了一次 RPC 的调用,callRPC 开头的那条记录。耗时 11ms, 但是这个 RPC 服务内部耗时花在哪里了,在这边不能直接查看,只能去另一个服务中查看,不是很方便。

谁说Cat不能做链路跟踪的,给我站出来插图

详细的我画了一张图说明下现在的问题:

谁说Cat不能做链路跟踪的,给我站出来插图(1)

从上图可以看出,一个请求经过了多个服务,每个服务中对远程调用或者本地调用都有埋点,这样就能监控到调用的异常和性能指标。

下面一部分是在 Cat 中我们去查看这些指标的场景,Cat 中的数据展示是以项目维度来展示的,所以每个服务都有自己的监控数据。

如果我想要知道刚刚那次请求,在整个链路中哪里最慢,耗时在哪里,我得分别去 4 个服务下面才能看到这些信息,不直观。

实现方式

如下图所示:

从网关到服务,从服务到服务,都需要将 Trace 信息进行传递才可以将整个链路串起来。只有串起来了才可以在 Cat 中查看到整个链路的耗时信息。

谁说Cat不能做链路跟踪的,给我站出来插图(2)

本文需要实现的效果就是可以在请求的入口处(网关),查看到这个请求经过的所有服务,每个服务中的耗时情况。

要想将整个请求都串连起来,必须要有一个唯一的请求标识,一般我们称之为 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));
    }
}

如果用的是 Dubbo 的话可以用 Dubbo 的 Filter 来实现相同的效果。

最终的效果如下图,调用了 articles/newest 接口,网关将请求转发到 article-provider 服务,article-provider 中又调用了 user-provider 的 users/uid 接口获取用户信息,最重要的是 user-provider 中有哪些操作的耗时在这里也能直观的看到,非常方便。

谁说Cat不能做链路跟踪的,给我站出来插图(3)

完整源码参考: https://github.com/yinjihuan/kitty

本站资源均源自网络,若涉及您的版权、知识产权或其他利益,请附上版权证明邮件告知。收到您的邮件后,我们将在72小时内删除。
若下载资源地址错误或链接跳转错误请联系站长。站长q:770044133。

» 谁说Cat不能做链路跟踪的,给我站出来

发表评论

免登录下载网,提供全网最优质的资源集合!