精华内容
下载资源
问答
  • 最近为我们的游戏服务器接入链路追踪系统,了解了公司内、公司外的多个链路追踪组件,链路追踪系统可以用于监控分布式系统的性能、调用关系、定位问题等。链路追踪中有个很重要的概念叫做OpenTracing,它不是一个可以...

    最近为我们的游戏服务器接入链路追踪系统,了解了公司内、公司外的多个链路追踪组件,链路追踪系统可以用于监控分布式系统的性能、调用关系、定位问题等。

    链路追踪中有个很重要的概念叫做OpenTracing,它不是一个可以下载、可以引入的组件或者程序,而是一种标准,在java里可以理解为定义了一系列链路追踪的interface,各个开发基础组件的公司可以基于这些接口,开发自己的链路追踪系统。而业务开发者,只需要通过opentracing的api来进行业务埋点,具体实现可以随意选择,切换成本非常低,只需要修改数行代码就可以从一个链路追踪组件切换到另一个链路追踪组件;前提就是这些组件是符合Opentracing规范。

    后面我将介绍下我们的游戏服务器引入链路追踪系统是解决了什么问题,针对具体的问题,我也会从两方面介绍:

    1. 如果没有Opentracing,我如何去实现,实现方式存在哪些问题

    2. Opentracing如何解决上面提到的问题

    通过两者的对比,更好的理解Opentracing的设计。

    链路追踪有什么用

    函数调用监控

    随着每个迭代需求的增加,我们的游戏服务器业务代码越来越多,玩家登录需要处理的玩法系统也越来越多,导致登录慢,如何去定位哪一部分耗时最多,从而去优化呢?

    假设我们的登录逻辑如下

    public void login(User user) {
        initBuilding(user); // 建筑
        initGodAnimal(user);// 神兽
        initArmy(); // 士兵
        initFriend(); // 好友
        initAlliance(); // 联盟
        ... // 好几十个其他模块
        ...
    }
    • 最土的办法,加日志

    public void login(User user) {
        long time = nowTime();
        initBuilding(user); // 建筑
        log.error("buiding cost:{}", nowTime() - time);
        time = nowTime();
        initGodAnimal(user);// 神兽
        log.error("god animal cost:{}", nowTime() - time);
        initArmy(); // 士兵
        // log.error....
        initFriend(); // 好友
        // log.error...
        initAlliance(); // 联盟
        ... // 好几十个其他模块
        ...
    }
    • 稍微优美点的方法,将监控的逻辑构造出一个对象,让监控代码收敛,简洁一些

    public void login(User user) {
        Monitor mon = new Monitor("login");
        initBuilding(user); // 建筑
        mon.record("building");
        initGodAnimal(user);// 神兽
        mon.record("godanimal");
        initArmy(); // 士兵
        mon.record("Army");
        initFriend(); // 好友
        ...
        initAlliance(); // 联盟
        ... // 好几十个其他模块
        ...
        mon.finish(); // 结束统计,输出结果
    }
    // Monitor内部维护一个时间和一个stringbuilder对象,封装了统计耗时,输出结果的逻辑,用起来稍微简单些

    最终得到的结果就是日志文件,结果如下:

    building cost 100ms, god animal cost 200 ms, xxxx cost 300......

    这个日志结果存在几个问题:

    第一个问题:如果只有三个模块,日志不长,其实看着也还行吧,但是我们服务器现状是,一条日志可以有20行左右,全是这样的xxx cost yyy ms,非常的不直观。

    第二个问题:统计颗粒度不够细,比如得出了god animal模块很慢,但是initGodAnimal里可能也包含了很多的逻辑,包含好几次的db、redis查询,我们的追踪日志需要继续的细化。

    第三个问题:文本可视化程度不够,方法间调用关系不明确,日志里都属于同一层,体现不出调用关系

    如何细化?

    • 日志的方式如何细化

    initBuildinginitGodAnimal函数中像之前一样继续加日志

    • 构造出监控对象的如何继续细化?

    // 将mon对象传入每一个子方法,子方法调用Monitor.record继续记录耗时
    public void login(User user) {
        Monitor mon = new Monitor("login");
        initBuilding(mon, user); // 建筑
        initGodAnimal(mon, user);// 神兽
        initArmy(mon); // 士兵
        initFriend(mon); // 好友
        // .... 
        mon.finish(); // 结束统计,输出结果
    }

    上面的这种做法可以解决问题,但是很不优雅,需要修改几乎所有方法的签名。

    • Opentracing用法

    public void login(User user) {
        Tracer tracer = GlobalTracer.get();
        Span span = tracer.buildSpan("login").start(); // 构造一个span对象
        span.setTag("user_id", user.id); // 可以给span设置一些信息
        try (Scope scope = tracer.scopeManager().activate(span)) {
            initBuilding(user); // 建筑
            initGodAnimal(user);// 神兽
            initArmy(); // 士兵
            initFriend(); // 好友
            ...
            initAlliance(); // 联盟
            ... // 好几十个其他模块
            ...
        } finally {
            span.finish();// 结束统计
        }
    }

    // initBuilding()
    public void initBuilding() {
        Tracer tracer = GlobalTracer.get();
        Span span = tracer.buildSpan("login").start();
        // 业务逻辑
        span.finish();
    }
    // 其他方法类似

    这里的TracerSpanScope等都是Opentracing定义的接口

    GlobalTracer是一个工具类(也可以自己实现个类似的,这个应该不属于opentracing规范内的东西),可以通过get方法获取一个单例的Tracer对象,前面提到的不同基础组件开发公司,主要开发的就是Tracer的具体实现,我们只需要在程序启动时,将第三方实现好的Tracer对象注入到GlobalTracer中,因此在不同的第三方链路追踪系统之间切换时,只需要修改一下注入对象;而业务代码的埋点逻辑,我们都是基于interface编程,所以无需修改。即使我们在启动服务器时,没有向GlobalTracer中注入任何对象,它内部也默认实现了一个没有任何逻辑的NoopTracer,我们的代码执行也不会有任何异常。通过这种单例模式,可以不需要将 tracer对象作为参数传入每一个需要监控的方法。

    一个Span对象就是一条监控记录,与前面自己实现的Monitor不同的地方是,新的代码中构造了很多个Span对象,但是之前的Monitor对象只有一个。Span只关注自己需要监控的代码,比如login方法中的Span,统计的是登录的耗时,比如initBuilding中的span统计的是初始化建筑的耗时。

    span的大概结构如下:

    public Span {
        // 代表一条链路,同一条链路上,所有的span的trace_id相同
        // 以上面的登录代码举例
        // 一个玩家的一次登录的完整过程算一条链路
        // login, building, godAniaml中构造的span的trace_id都是相等的
        String traceId;
        // 当前span节点的ID,唯一
        String spanId;
        // 父节点id,表示调用关系
        // 以上面登录代码举例
        // login节点是所有init方法中父节点
        String parentId;
        // 其他一些记录监控指标的信息
    }

    spanId是每个Span节点唯一的,很好生成,不介绍了。但是traceId,parentId这些与上下文相关联的信息如何写入呢?

    一条链路,总归会有一个起始节点,对登录来说,就是我们的login方法入口。初始节点就是一个创建traceId的合适地方,因为代表了一条链路的开始。

    如何判断是不是链路的起点呢?上面的代码中,其实我们创建span的方法都是一模一样的。区别在于login方法中多了Scope scope = tracer.scopeManager().activate(span)这样的一行代码,而其他init方法中没有。

    ScopeManager是上下文管理器,也是一个接口,可以有不同的实现。以大多数java服务器应用的并发模型来说,都是采用多线程的方式。即玩家登录的处理逻辑是靠一个线程池来处理的,一个线程在一段时间内,处理的是同一个玩家的登录请求,登录的整条链路都是在一个线程内处理的(rpc,mysql等远程调用,对本机来说还是一个线程)。则可以把链路的上下文信息放入线程中,即ThreadLocal

    针对于ThreadLocalScopeManager,activate(span)方法就是将当前这个span对象存到线程本地变量中,当下一个Span对象构造时,就判断下当前本地变量里是否已经存在span对象(其实是一个链表结构,因为可以有多层调用),如果存在,则认为线程本地变量中的span对象是自己的父节点,则可以把自己相应的traceId,parentId字段补充完整。并且因为threadLocal的存在,span对象也不需要像上面自己实现的monitor对象一样作为参数传入每一个方法。

    ScopeManager一般会实现autoClose接口,所以用try语法糖来实现自动关闭,从而将本地变量中的Span对象删除。

    通过ScopeManager对象,就可以体现出不同span之间的调用关系,当我们需要对当前监控的方法的子方法进行调用时,就可以通过ScopeManager来体现出这种调用的父子关系。

    ef2f064e2fe90c4366af7ca7002f5f4e.png

    span

    在时序图上,就可以展示出如上图这样的效果,整个login耗时假设100ms,前30ms用来initBuilding,接下里的20ms用于initArmy…不仅每个阶段的耗时可以统计出来,也能把他们的时序顺序,调用关系充分的体现出来。

    远程调用监控

    上面都在将本地的调用监控,现在的系统大多数是分布式系统,存在各种远程调用,mysql,redis等,这些也是我们需要监控的地方。

    拿上面的登录流程举例,我们得知登录流程慢,其实可以以90%以上的信心认为是db查询耗时太慢导致登录耗时久,因为正常的内存操作都是非常快的,不会有太大问题。上面的那种埋点方式,重复代码多,作用其实也不大。因为没有埋在关键点位:rpc调用,mysql,redis这些耗时的操作上。

    mysql,redis埋点

    db查询由于io和网络延迟的存在,是耗时最严重的地方,也是监控需要重点覆盖的地方。只需要找到这些调用最底层的地方,进行统一埋点构造span对象,就可以监控所有的db操作。前面提到Span对象可以设置tag,在这里可以把db语句等放置进去

    rpc埋点

    mysql,redis也可以认为是远程调用,但是与一般rpc相比还是存在一些差异。当我们访问mysql和redis时,可以认为mysql,redis服务器就是终点了,它们除了处理我们的请求,不会主动的发起其他的请求或者子调用。

    但是rpc服务器就不一样了,比如A服务器调用了B服务器的一个接口,B服务器的处理逻辑也是一条复杂的链路,由多个子调用组成。前面是通过ScopeManager来控制一个进程内不同span之间的调用关系,但是AB服务器不是同一个进程,ScopeManager显然做不到这件事。那么在B服务器中创建的span对象,他的traceId,parentId该如何赋值呢?

    B服务器的traceId,parentId应该继承自A服务器,所以需要一个机制,来将A服务器的traceId,parentId来传送给B服务器。

    Tracer定义了两个接口来实现不同进程间传递上下文的需求:Tracer.Inject(…) 和 Tracer.Extract(…)。

    inject方法可以将上下文信息以指定的方式序列化,rpc client只需要将序列化得到的对象当作rpc调用中的一个参数传出去,rpc server端读取这个参数,将其反序列化得到SpanContext对象,然后rpc server在创建自己的span对象时,基本步骤与之前完全一样,只需要在创建第一个span对象时将得到的spanContext对象设置为自己的父节点(即为自己创建的span对象的traceId,parentId进行赋值)。

    最终A,B服务器创建的span对象都会发送到统一的后端服务器。这个服务器则根据traceid,spanid,parentid来将这些单独的span对象相互关联起来,形成调用链。

    链路可视化界面

    前面提到了,日志形式的监控,可视化非常差,不能让人直观的看出哪个环节慢了,不同模块的调用、时序关系等,但是开源的链路追踪系统,他们的后台可视化界面都非常的清晰。我们的服务器最终选用了uber开源的jaeger来做链路追踪。

    以login方法为root span节点(root节点用来将后续所有的子调用关联起来),mysql,redis,rpc最底层通用接口进行埋点,所有init方法无需创建新的span(基于我们对耗时都处于mysql,redis,rpc的判断)

    登录效果如下:

    1bb26eca7e9691f5e284e268cf930309.png

    span

    可以看出登录总共耗时732ms,mysql和redis总共执行次数为115次,每一次的查询语句,耗时、时序关系在上面都显示的清清楚楚。

    有了这个可视化界面可以帮助我们发现很多问题:

    1. 某些sql语句耗时明显过大,想办法优化

    2. 有几条sql在一次登录中居然出现了十几次,需要优化处理逻辑

    参考链接

    • opentracing官网

    • opentracing中文文档

    • opentracing java api

    展开全文
  • 链路追踪

    2019-04-18 21:44:00
    服务追踪时候,追踪一次请求,traceId向下穿透,最简单的方法可以扩展一个参数来标识。 这种方式比较low,可以使用threadlocal进行隐式传参 MDC ---- Mapped Diagnostic Context 在设置日志格式时候可以...

    服务追踪时候,追踪一次请求,traceId向下穿透,最简单的方法可以扩展一个参数来标识。

    这种方式比较low,可以使用threadlocal进行隐式传参

     

    MDC  ----  Mapped Diagnostic Context

    在设置日志格式时候可以携带traceId

    以上要求场景要求在同一个线程内调用,也就是同步调用。

    但是上述都是在同一个系统中,也就是同一个jvm中进行调用。

    分布式调用不能用,

    分布式调用一般分为两种,dubbo和spring cloud

     

     消费方放入traceId,使用com.alibaba.dubbo.rpc.Filter

     

    同理,服务方使用filter获取traceId

     

     

    转载于:https://www.cnblogs.com/huangzhang/p/10732633.html

    展开全文
  • zipkin链路追踪

    2020-12-18 10:18:54
    zipkin链路追踪jar包
  • SpringCloud Alibaba - 链路追踪(浅谈链路追踪 / 阿里组件 并没有链路追踪,应该选取哪一种使用好)回溯链路追踪(介绍)基本实现原理常用组件 回溯 前面的章节讲解了微服务的互相调用,以及注册发现,熔断,网关...

    SpringCloud Alibaba - 链路追踪(浅谈链路追踪 / 阿里组件 并没有链路追踪,应该选取哪一种使用好)

    回溯

    前面的章节讲解了微服务的互相调用,以及注册发现,熔断,网关等等,但是这些操作还不足以支撑项目的开发,我们还需要对程序的各方面分析等等,那么这章节讲解 链路追踪 ,不过和网关一样,Alibaba并没有开源相对应的组件,所以我们需要自己进行选择。

    链路追踪(介绍)

    在大型系统的微服务化构建中,一个系统被拆分成了许多模块。这些模块负责不同的功能,组合成系统,最终可以提供丰富的功能。在这种架构中,一次请求往往需要涉及到多个服务。互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、有可能布在了几千台服务器,横跨多个不同的数据中心,也就意味着这种架构形式也会存在一些问题:

    • 如何快速发现问题?
    • 如何判断故障影响范围?
    • 如何梳理服务依赖以及依赖的合理性?
    • 如何分析链路性能问题以及实时容量规划?

    在这里插入图片描述
    就是这样一个调用链,一个用户请求了应用A,应用A需要请求应用B和应用C,而应用C需要请求应用D和应用E。

    分布式链路追踪(Distributed Tracing),就是将一次分布式请求还原成调用链路,进行日志记录,性能监控并将一次分布式请求的调用情况集中展示。比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。

    基本实现原理

    如果想知道一个接口在哪个环节出现了问题,就必须清楚该接口调用了哪些服务,以及调用的顺序,如果把这些服务串起来,看起来就像链条一样,我们称其为调用链。

    在这里插入图片描述

    想要实现调用链,就要为每次调用做个标识,然后将服务按标识大小排列,可以更清晰地看出调用顺序,我们暂且将该标识命名为spanid。

    在这里插入图片描述

    实际场景中,我们需要知道某次请求调用的情况,所以只有spanid还不够,得为每次请求做个唯一标识,这样才能根据标识查出本次请求调用的所有服务,而这个标识我们命名为traceid。

    在这里插入图片描述
    现在根据spanid可以轻易地知道被调用服务的先后顺序,但无法体现调用的层级关系,正如下图所示,多个服务可能是逐级调用的链条,也可能是同时被同一个服务调用。

    在这里插入图片描述
    所以应该每次都记录下是谁调用的,我们用parentid作为这个标识的名字。

    在这里插入图片描述
    到现在,已经知道调用顺序和层级关系了,但是接口出现问题后,还是不能找到出问题的环节,如果某个服务有问题,那个被调用执行的服务一定耗时很长,要想计算出耗时,上述的三个标识还不够,还需要加上时间戳,时间戳可以更精细一点,精确到微秒级。

    在这里插入图片描述
    只记录发起调用时的时间戳还算不出耗时,要记录下服务返回时的时间戳,有始有终才能算出时间差,既然返回的也记了,就把上述的三个标识都记一下吧,不然区分不出是谁的时间戳。

    在这里插入图片描述
    虽然能计算出从服务调用到服务返回的总耗时,但是这个时间包含了服务的执行时间和网络延迟,有时候我们需要区分出这两类时间以方便做针对性优化。那如何计算网络延迟呢?我们可以把调用和返回的过程分为以下四个事件。

    • Client Sent简称cs,客户端发起调用请求到服务端。
    • Server Received简称sr,指服务端接收到了客户端的调用请求。
    • Server Sent简称ss,指服务端完成了处理,准备将信息返给客户端。
    • Client Received简称cr,指客户端接收到了服务端的返回信息。

    在这里插入图片描述
    假如在这四个事件发生时记录下时间戳,就可以轻松计算出耗时,比如sr减去cs就是调用时的网络延迟,ss减去sr就是服务执行时间,cr减去ss就是服务响应的延迟,cr减cs就是整个服务调用执行的时间。

    在这里插入图片描述

    其实span块内除了记录这几个参数之外,还可以记录一些其他信息,比如发起调用服务名称、被调服务名称、返回结果、IP、调用服务的名称等,最后,我们再把相同spanid的信息合成一个大的span块,就完成了一个完整的调用链。

    PS(实现原理编写,参考 一文读懂链路追踪)。

    常用组件

    1. cat 由大众点评开源,基于Java开发的实时应用监控平台,包括实时应用监控,业务监控 。 集成方案是通过代码埋点的方式来实现监控,比如: 拦截器,过滤器等。 对代码的侵入性很大,集成成本较高。风险较大。
    2. zipkin 由Twitter公司开源,开放源代码分布式的跟踪系统,用于收集服务的定时数据,以解决微服务架构中的延迟问题,包括:数据的收集、存储、查找和展现。该产品结合spring-cloud-sleuth使用较为简单, 集成很方便, 但是功能较简单。
    3. pinpoint Pinpoint是韩国人开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI功能强大,接入端无代码侵入。
    4. SkyWalking 是本土开源的基于字节码注入的调用链分析,以及应用监控分析工具。特点是支持多种插件,UI功能较强,接入端无代码侵入。目前已加入Apache孵化器。
    5. Sleuth SpringCloud 提供的分布式系统中链路追踪解决方案。

    SpringCloud alibaba技术栈中并没有提供自己的链路追踪技术的,我们可以采用Sleuth +Zinkin来做链路追踪解决方案。这也是目前企业中较为流行的方案。

    展开全文
  • 什么是链路追踪分布式系统变得日趋复杂,越来越多的组件开始走向分布式化,如微服务、分布式数据库、分布式缓存等,使得后台服务构成了一种复杂的分布式网络。在服务能力提升的同时,复杂的网络结构也使问题定位更加...

    点击蓝色“程序猿DD”关注我哟

    66d4bd954fa4f5a6d90142a0923b2f1e.png

    来源:http://t.cn/Ef9Hupk

    起因

    最近一直在做分布式链路追踪的调研和实践,整理一下其中的知识点。

    什么是链路追踪

    分布式系统变得日趋复杂,越来越多的组件开始走向分布式化,如微服务、分布式数据库、分布式缓存等,使得后台服务构成了一种复杂的分布式网络。在服务能力提升的同时,复杂的网络结构也使问题定位更加困难。在一个请求在经过诸多服务过程中,出现了某一个调用失败的情况,查询具体的异常由哪一个服务引起的就变得十分抓狂,问题定位和处理效率是也会非常低。

    分布式链路追踪就是将一次分布式请求还原成调用链路,将一次分布式请求的调用情况集中展示,比如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等等。

    Dapper

    目前业界的链路追踪系统,如Twitter的Zipkin,Uber的Jaeger,阿里的鹰眼,美团的Mtrace等都基本被启发于google发表的Dapper。 Dapper阐述了分布式系统,特别是微服务架构中链路追踪的概念、数据表示、埋点、传递、收集、存储与展示等技术细节。

    Trace、Span、Annotations

    为了实现链路追踪,dapper提出了trace,span,annotation的概念。 Trace的含义比较直观,就是链路,指一个请求经过后端所有服务的路径,可以用下面树状的图形表示。每一条链路都用一个全局唯一的traceid来标识。

    e63b8eee0316ffe8d49bca9b5079fcba.png

    Span之间存在着父子关系,上游的span是下游的父span,例如图中”frontend.request”会调用”backend.dosomething”,”backend.dosomething”便成为”frontend.request”的子span。

    8f25c0b83439835f0b90388f64a781ce.png

    链路中的rpc调用由span来表示,对应着树状图中的边,每个span由spanid和parentid来标识,spanid在一条链路中唯一。 下图是dapper论文中给出的一个”hepler.call”调用的span详解。 一个span一般由client和server两个部分的信息组成。按照时间顺序来解释,client节点(或者是调用方)首先发出请求,产生”client send”(cs)事件,紧接着server节点(或者是提供方)收到请求,产生”server receive”(sr)事件,server处理完成之后回复给client,产生”server send”事件,最后client收到回复,产生”client receive”事件。 Client与server两个节点的span信息合并成一次完整的调用,即一个完整的span。

    c758be561e1d5a78a3766425e025abbf.png

    Dapper中还定义了annotation的概念,用于用户自定义事件,如图二中的”foo”,用来辅助定位问题。 值得一提的是,zipkin中把cs,cr,ss,sr这几个事件称之为annotation,而对应dapper中的annotation在zipkin v1的数据模型中被称之为binaryAnnotation。

    带内数据与带外数据

    链路信息的还原依赖于两种数据,一种是各个节点产生的事件,如cs,ss,称之为带外数据,这些数据可以由节点独立生成,并且需要集中上报到存储端。 另一种数据是traceid,spanid,parentid,用来标识trace,span,以及span在一个trace中的位置。这些数据需要从链路的起点一直传递到终点,称之为带内数据。 通过带内数据的传递,可以将一个链路的所有过程串起来;通过带外数据,可以在存储端分析更多链路的细节。

    采样

    由于每一个请求就会生成一个链路,为了减少性能消耗,避免存储资源的浪费,dapper并不会上报所有的span数据,而是使用采样的方式。通过采集端自适应地调整采样率,控制span上报的数量,可以在发现性能瓶颈的同时,有效减少性能损耗。采样率的概念在其他的追踪系统中也被广泛使用。在zipkin小节中将更具体阐述zipkin的采样机制。

    存储

    链路中的span数据经过收集和上报后会集中存储在一个地方,Dapper使用了BigTable数据仓库,如下图所示,由于每种trace的span个数不尽相同,使得BigTable稀疏表格布局很适合这种场景,并且分散的span进行存储时按照traceid和spanid便可以插入到对应的行列中,使得收集程序可以无需做任何计算且无状态。同时链路的查询也十分方便,即取表中的一行。

    b04648abc74f713b979f5795d8d22331.png

    Zipkin

    Zipkin是dapper的一种开源实现,也是业界做链路追踪系统的一个重要参考,其系统也可以即插即用。

    架构

    Zipkin的架构中包含Reporter,Transport,Colletor,Storage,API,UI几个部分。

    9fc3afe337f2b4a69574747732ef4d45.png

    其中Reporter集成在每个服务的代码中,负责Span的生成,带内数据(traceid等)的传递,带外数据(span)的上报,采样控制。Transport部分为带外数据上报的通道,zipkin支持http和kafka两种方式。Colletor负责接收带外数据,并插入到集中存储中。Storage为存储组件,适配底层的存储系统,zipkin提供默认的in-memory存储,并支持Mysql,Cassandra,ElasticSearch存储系统。API提供查询、分析和上报链路的接口。接口的定义见zipkin-api。UI用于展示页面展示。

    47299bb0552cfd6cf052cec9c0aba60e.png

    Zipkin将Colletor/Storage/API/UI打包为jar包,可以直接下载运行。

    数据模型

    这里的数据模型为zipkin v2版本的数据模型。

    Span

    trace_id为16位或32位的hex字符串, idparent_id为16位hex字符串, 如果没有父span, parent_id为空。 kind标识服务节点的类型,有通信模型,cs和生产者消费者模型。 name为span的名字,如rpc调用的名字。 timestamp为span生成的时间戳,微秒。 duration为span的持续时间,client端,即为cr-ss的时间。 local_endpoint为本地节点信息,包含节点名称,ip与端口。 remote_endpoint为远端节点信息。 annotations为事件列表,每个事件用事件时间戳和名字表示。 tags为用户自定义的kv信息,如{“user-id”:”lidawn”}。 debug表示是否为调试,该选项会无视采样概率,使所有span上报。 shared这个字段暂时没有太理解==。

    message Span {

    bytes trace_id = 1;

    bytes parent_id = 2;

    bytes id = 3;

    enum Kind {

    SPAN_KIND_UNSPECIFIED = 0;

    CLIENT = 1;

    SERVER = 2;

    PRODUCER = 3;

    CONSUMER = 4;

    }

    Kind kind = 4;

    string name = 5;

    fixed64 timestamp = 6;

    uint64 duration = 7;

    Endpoint local_endpoint = 8;

    Endpoint remote_endpoint = 9;

    repeated Annotation annotations = 10;

    map<string, string> tags = 11;

    bool debug = 12;

    bool shared = 13;

    }

    message Endpoint {

    string service_name = 1;

    bytes ipv4 = 2;

    bytes ipv6 = 3;

    int32 port = 4;

    }

    message Annotation {

    fixed64 timestamp = 1;

    string value = 2;

    }

    带内数据与采样机制

    Zipkin中对带内数据的传递有更加详细的描述。带内数据被称为 b3-propagation,包含 TraceId,SpanId,ParentSpanId,Sampled四个字段,每个server在生成span之后会得到TraceId,SpanId,ParentSpanId,穿递到下游server之后,下游server可以知道自己接下来要生成的span属于哪一条trace,并处在trace的哪一个位置。

    由于带内数据涉及到进程之间通信,所以一般是由框架来做带内数据传递,这样可以减少代码的侵入性。如果服务之间使用http通信,则可以使用 X-开头的自定义http head来传递带内数据。或者如grpc框架,使用clientContext机制在调用之间传递自定义的字段。目前开源的zipkin客户端一般只支持http和grpc两种方式。

    Zipkin的采样字段Sampled有四种状态 Defer/Deny/Accept/Debug,采样的一个重要前提是下游要尊重上游的采样决定,不能随意更改sampled字段。 Defer代表该span的采样状态还未决定,下游收到该状态时则可以对sampled字段重新赋值。 Deny代表该span不上报。 Accept代表span需要上报。 Debug一般用于开发环境,强制上报。

    Root_span的sampled字段由系统的采样率来决定。如采样率为50%,则一半的带内数据中sampled字段为accept,其他为deny。

    数据埋点及上报过程

    根据zipkin的span定义,模拟一个简单的调用过程,分析数据埋点和上报过程。

    f8444a86d7c0b773d42914c4e3bf0457.png

    1. server-1发起对server-2的调用,生成一个rootspan, 生成traceid,id,parentid为空,并记录kind为CLIENT,name,timestamp,localendpoint(server-1)信息,并将traceid,id,parentid,sampled信息传递给server-2。

    2. server-2收到server-1的请求,并收到traceid,id,parentid,sampled信息,生成一个相同的span,并记录kind为SERVER,name,timestamp,local_endpoint(server-2)信息。

    3. server-2发起对server-3的调用,生成一个新的span,该span为rootspan的子span。 并记录kind为CLIENT,name,timestamp,localendpoint(server-2)信息,并将traceid,id,parentid,sampled信息传递给server-3。

    4. server-3收到server-2的请求,并收到traceid,id,parentid,sampled信息,生成一个相同的span,并记录kind为SERVER,name,timestamp,local_endpoint(server-3)信息。

    5. server-3回复server-2的调用,记录duration,并上报span。

    6. server-2收到server-3的回复,记录duration,并上报span。

    7. server-2回复server-1的调用,记录duration,并上报span。

    8. server-1收到server-2的回复,记录duration,并上报span。

    整个过程中上报4个临时的span,最终在zipkin中被合并和存储为两个span。

    Open-Tracing

    由于各种分布式追踪系统层出不穷,且有着相似的API语法,但各种语言的开发人员依然很难将他们各自的系统和特定的分布式追踪系统进行整合。在这种情况下,OpenTracing规范出现了。 OpenTracing通过提供平台无关、厂商无关的API,使得开发人员能够方便的添加(或更换)追踪系统的实现。OpenTracing通过定义的API,可实现将监控数据记录到一个可插拔的tracer上。

    Opentracing api的定义可以查看中文文档, 其并没有具体的实现。对于现有的系统,如zipkin适配opentracing,则需要额外基于现有的client编写适配代码。

    以上。

    参考

    1. Zipkin - https://zipkin.io

    2. Dapper - https://storage.googleapis.com/pub-tools-public-publication-data/pdf/36356.pdf

    3. Jaeger - https://www.jaegertracing.io/

    4. 鹰眼 - https://cn.aliyun.com/aliware/news/monitoringsolution

    5. Mtrace - https://tech.meituan.com/mt_mtrace.html

    6. Zipkin-b3-propagation - https://github.com/openzipkin/b3-propagation

    7. Zipkin-api - https://zipkin.io/zipkin-api/#/default/post_spans

    8. Zipkin-proto - https://github.com/openzipkin/zipkin-api/blob/master/zipkin.proto

    9. OpenTracing - https://opentracing.io

    10. OpenTracing中文 - https://wu-sheng.gitbooks.io/opentracing-io/content/

    号外:最近整理了之前编写的一系列内容做成了PDF,关注我并回复相应口令获取:

    001 :领取《Spring Boot基础教程》

    - 002 :领取《Spring Cloud基础教程》

    更多内容陆续奉上,敬请期待 b3548d0c0948c0c0ce6f49235b948faa.png

    - END -

     近期热文:

    • 为什么美国程序员工作比中国程序员工作轻松、加班少?

    • Spring Cloud Alibaba 基础教程整理

    • 我为啥不看好ServiceMesh

    • 敏捷团队的病与药

    • 分布式系统关注点:弹性架构

    • GitHub 寻宝指南

    • 虎牙直播在微服务改造方面的实践和总结

    • 有赞搜索系统的架构演进

    • 在前后端分离的路上承受了多少痛?

    • 中台是个什么鬼?

    2019

    我在星球与大家聊聊技术人的斜杠生活

    f547d00fc3886da4e77b1bbbc0283cdf.png

    看完,赶紧点个“好看”鸭

    点鸭点鸭

                                                                                                           ↓↓↓↓

    展开全文
  • 其中链路追踪技术以其在APM领域的优异表现,成为了分布式架构中不可或缺的一部分。在本文中,我们将谈谈它的一些经典应用场景,以及笔者所在的团队如何利用链路追踪技术提升团队的研发效能。链路追踪背景如图所示,...
  • skywalking是分布式系统的应用程序性能监视、分布式链路追踪工具,跟听云、博瑞等一系列服务器监控组件服务类似,开源的相关类似组件有zipkin、pinpoint等,由于笔者所在项目组准备升级springcloud,缺少相关链路...
  • 链路追踪Trace 和 SpanSpan操作RPC Server端(HTTP Server类似)RPC Client端获取信息调用链监控链路追踪Trace 和 Span在OpenTracing(基本是行业标准了~)中,一个重要的概念是“trace”,它表示从头到尾的一个请求的...
  • 本片介绍go micro中使用jaeger作为链路追踪的使用jaeger相关知识请见官方文档,这里使用docker启动gaeger,作为测试使用启动jaegerdocker run -d -p 6831:6831/udp -p 16686:16686 jaegertracing/all-in-one:latest...
  • 一、导读 随着ERP的部署架构越来越复杂,微应用分布式部署架构在给用户带来高性能...链路追踪还有一个好处,针对性能慢的页面,原来很难快速定位到慢的具体点,通过借助链路追踪,能快速掌握每个请求执行了哪些操作...
  • skywalking是什么,有什么用?Skywalking 是一个APM系统,即应用性能监控系统,为微服务架构和云原生架构...目前支持链路追踪和监控应用组件如下,基本涵盖主流框架和容器,如国产PRC Dubbo和motan等,国际化的spr...
  • 1、概述在分布式服务时代,服务之间的请求域调用不再是简单的直连方式,注册中心的出现,让服务治理更加便利,也对服务之间的链路追踪提出了更高的要求。分布式链路追踪就是将一次分布式请求还原成调用链路,将一次...
  • 在微服务架构的系统中,请求在各服务之间流转,调用链错综复杂,一旦出现了问题和异常,很难追查定位,这个时候就需要链路追踪来帮忙了。链路追踪系统能追踪并记录请求在系统中的调用顺序,调用时间等一系列关键信息...
  • 概述首先同步下项目概况:上篇文章分享了,路由中间件 - 捕获异常,这篇文章咱们分享:路由中间件 - Jaeger 链路追踪。啥是链路追踪?我理解链路追踪其实是为微服务架构提供服务的,当一个请求中,请求了多个服务...
  • SpringBoot之微服务日志链路追踪简介在微服务里,业务出现问题或者程序出的任何问题,都少不了查看日志,一般我们使用 ELK 相关的日志收集工具,服务多的情况下,业务问题也是有些难以排查,只能确定大致时间定位...
  • 链路追踪是 Pandora 推出的链路追踪应用,兼容 zipkin、pinpoint、skywalking 和 jaeger 等开源 Tracing 方案。通过 logkit-pro 采集 zipkin、pinpoint、skywalking 和 jaeger 等开源 Tracing 方案的埋点日志数据...
  • 分布式链路追踪系统的介绍 一、分布式链路追踪可以做什么? 1.1简单集群架构&微服务架构 先来看下最简单的网站集群架构图: 图1 在这个图里,存在从1~n个服务器,通过负载均衡器SLB进行请求分发,在每...
  • 微服务链路追踪

    2021-02-26 12:30:41
    目录1 分布式计算八大误区2 链路追踪的必要性3 链路追踪要考虑的几个问题4 Sleuth简介5 使用5.1 Sleuth单独5.2 zipkin 1 分布式计算八大误区 网络可靠。 延迟为零。 带宽无限。 网络绝对安全。 网络拓扑不会改变。 ...
  • 概述首先同步下项目概况:上篇文章分享了,路由中间件 - Jaeger 链路追踪(理论篇)。这篇文章咱们分享:路由中间件 - Jaeger 链路追踪(实战篇)。说实话,这篇文章确实让大家久等了,主要是里面有一些技术点都是刚刚...
  • 演示链路追踪效果。分布式服务追踪与调用链系统产生的背景在微服务框架中,一个由客户端发起的请求在后端系统中会经过多个不同的服务节点调用来协同产生最后的请求结果,每一个前端请求都会形成一条复杂的分布式服务...
  • ZipKin链路追踪

    2020-03-10 15:31:09
    ZipKin官网 ZipKin链路追踪介绍
  • 目前分布式链路追踪系统基本都是根据谷歌的《Dapper大规模分布式系统的跟踪系统》这篇论文发展而来,主流的有zipkin,pinpoint,skywalking,cat,jaeger等。本次APM系统选型主要对比pinpoint和skywalking。直接否定...
  • Skywalking 链路追踪

    2021-01-20 14:03:44
    Skywalking 链路追踪 Skywalking 根据官方的解释,Skywalking是一个可观测性平台(Observability Analysis Platform简称 OAP)和应用性能管理系统(Application Performance Management 简称 APM)。提供分布式链路...
  • 链路追踪微服务架构下,所有的服务都分散在不同的地方,一旦某个服务出现问题,排查起来很费时费力。所以在微服务的演进下,需要一个全链路追踪系统来分析服务的运行状态。go-micro的trace插件Micro通过Wrapper实现...
  • zipkin_rabbitmq链路追踪
  • 微服务-链路追踪

    2021-02-01 17:12:22
    文章目录微服务-链路追踪Sleuth+Zipkin1.打印日志2.聚合日志Zipkin3.持久化数据4.化数据采集RabbitMQSkywalking 微服务-链路追踪 通过链路追踪,可以记录请求在整个调用链路的日志信息、对应用性能进行监控、显示...
  • 这篇文章主要讲述服务追踪组件zipkin,Spring Cloud Sleuth集成了zipkin组件。
  • 链路追踪的原理衡量一个接口,我们一般会看三个指标:1、接口的 RT(Route-Target)你怎么知道?2、接口是否有异常响应?3、接口请求慢在哪里?1、单体架构时代在创业初期,我们的系统一般是单体架构,如下:对于单体架构...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,998
精华内容 1,599
关键字:

链路追踪