分布式跟踪系统(一):Zipkin的背景和设计

2017-07-21  本文已影响0人  yingyingguigui
9bdf758d-4242-3bcc-ad2a-2b95964d00ed.png

这里埋怨一下,Zipkin官网的内容太过简单(难道是因为懒才懒得去Apache孵化?),也许Twitter认为有谷歌Dapper那边文章就足够了吧。我们看上图,其中的S表示的是发送跟踪数据的客户端SDK还是Scribe的客户端(因为Twitter内部采用的就是Scribe来采集跟踪数据)?效果都一样,总而言之我们看到的就是各个应用、中间件甚至是数据库将跟踪数据发送到Zipkin服务器。

总体设计没什么特别,我们看下内部的数据模型是怎么设计的。一般的调用链都可以展现成一颗树,比如下面的简单调用:

2ef46adb-93e2-38f0-aae9-b8dda39fe7d2.png

上图描述的服务调用场景应该是很常见也很简单的调用场景了,一个请求通过Gateway服务路由到下游的Service1,然后Service1先调用服务Service2,拿到结果后再调用服务Service3,最后组合Service2和Service3服务的结果,通过Gateway返回给用户。我们用①②③④⑤⑥表示了RPC的顺序,那么,什么是span?span直译过来是"跨度",在谷歌的Dapper论文中表示跟踪树中树节点引用的数据结构体,span是跟踪系统中的基本数据单元,Dapper的论文中,并没有具体介绍span中的全部细节,但在Zipkin中,每个span中一般包含如下字段:

traceId:全局跟踪ID,用它来标记一次完整服务调用,所以和一次服务调用相关的span中的traceId都是相同的,Zipkin将具有相同traceId的span组装成跟踪树来直观的将调用链路图展现在我们面前。这里直接给出Zipkin官网中的一张Zipkin界面的图:

eff1e978-414f-3b77-821f-cd4098f41fc0.png
{
 
            "timestamp": 1476197069680000,
 
            "value": "cs",
 
            "endpoint": {
 
                "serviceName": "service1",
 
                "ipv4": "xxx.xxx.xxx.111"
 
            }
 
 }

那么,有哪些事件类型呢?答案是四种:cs(客户端/消费者发起请求)、cr(客户端/消费者接收到应答)、sr(服务端/生产者接收到请求)和ss(服务端/生产者发送应答)。可以看出,这四种事件类型的统计都应该是Zipkin提供客户端来做的,因为这些事件和业务无关,这也是为什么跟踪数据的采集适合放到中间件或者公共库来做的原因。

binaryAnnotations:业务标注列表,如果某些跟踪埋点需要带上部分业务数据(比如url地址、返回码和异常信息等),可以将需要的数据以键值对的形式放入到这个字段中。

说到这里,大家对span的印象可能还是有点模糊不清,于是我们继续拿图2的服务调用来举例,如果我们将图2的应用接入Zipkin,将会是下图的效果:

10865dce-3eb0-3b0d-a3c1-92ca6194561d.png

分布式跟踪系统(二):Zipkin的Span模型:http://manzhizhen.iteye.com/blog/2347153

   最后,给出图4四个服务采集的span数据样例:
# Gateway的span
 
{
 
    "traceId": "daaed0921874ebc3",
 
    "id": "daaed0921874ebc3",
 
    "name": "get",
 
    "timestamp": 1476197067420000,
 
    "duration": 4694000,
 
    "annotations": [
 
        {
 
            "timestamp": 1476197067420000,
 
            "value": "cs",
 
            "endpoint": {
 
                "serviceName": "gateway",
 
                "ipv4": "xxx.xxx.xxx.110"
 
            }
 
        },
 
        {
 
            "timestamp": 1476197072114000,
 
            "value": "cr",
 
            "endpoint": {
 
                "serviceName": "gateway",
 
                "ipv4": "xxx.xxx.xxx.110"
 
            }
 
        }
 
    ],
 
    "binaryAnnotations": [
 
        {
 
            "key": "http.url",
 
            "value": "[http://localhost:8080/service1](http://localhost:8080/service1)",
 
            "endpoint": {
 
                "serviceName": "gateway",
 
                "ipv4": "xxx.xxx.xxx.110"
 
            }
 
        }
 
    ]
 
}
 
 
 
# Service1的三个span
 
{
 
    "traceId": "daaed0921874ebc3",
 
    "id": "411d4c32c102a974",
 
    "name": "get",
 
    "parentId": "daaed0921874ebc3",
 
    "timestamp": 1476197069680000,
 
    "duration": 1168000,
 
    "annotations": [
 
        {
 
            "timestamp": 1476197069680000,
 
            "value": "cs",
 
            "endpoint": {
 
                "serviceName": "service1",
 
                "ipv4": "xxx.xxx.xxx.111"
 
            }
 
        },
 
        {
 
            "timestamp": 1476197070848000,
 
            "value": "cr",
 
            "endpoint": {
 
                "serviceName": "service1",
 
                "ipv4": "xxx.xxx.xxx.111"
 
            }
 
        }
 
    ],
 
    "binaryAnnotations": [
 
        {
 
            "key": "http.url",
 
            "value": "[http://localhost:8089/service2](http://localhost:8089/service2)",
 
            "endpoint": {
 
                "serviceName": "service1",
 
                "ipv4": "xxx.xxx.xxx.111"
 
            }
 
        }
 
    ]
 
}
 
 
 
{
 
    "traceId": "daaed0921874ebc3",
 
    "id": "7c0d7d897a858217",
 
    "name": "get",
 
    "parentId": "daaed0921874ebc3",
 
    "timestamp": 1476197070850000,
 
    "duration": 1216000,
 
    "annotations": [
 
        {
 
            "timestamp": 1476197070850000,
 
            "value": "cs",
 
            "endpoint": {
 
                "serviceName": "service1",
 
                "ipv4": "xxx.xxx.xxx.111"
 
            }
 
        },
 
        {
 
            "timestamp": 1476197072066000,
 
            "value": "cr",
 
            "endpoint": {
 
                "serviceName": "service1",
 
                "ipv4": "xxx.xxx.xxx.111"
 
            }
 
        }
 
    ],
 
    "binaryAnnotations": [
 
        {
 
            "key": "http.url",
 
            "value": "[http://localhost:8090/service3](http://localhost:8090/service3)",
 
            "endpoint": {
 
                "serviceName": "service1",
 
                "ipv4": "xxx.xxx.xxx.111"
 
            }
 
        }
 
    ]
 
}
 
 
 
{
 
    "traceId": "daaed0921874ebc3",
 
    "id": "daaed0921874ebc3",
 
    "name": "get",
 
    "timestamp": 1476197067623000,
 
    "duration": 4479000,
 
    "annotations": [
 
        {
 
            "timestamp": 1476197067623000,
 
            "value": "sr",
 
            "endpoint": {
 
                "serviceName": "service1",
 
                "ipv4": "xxx.xxx.xxx.111"
 
            }
 
        },
 
        {
 
            "timestamp": 1476197072102000,
 
            "value": "ss",
 
            "endpoint": {
 
                "serviceName": "service1",
 
                "ipv4": "xxx.xxx.xxx.111"
 
            }
 
        }
 
    ],
 
    "binaryAnnotations": [
 
        {
 
            "key": "http.status_code",
 
            "value": "200",
 
            "endpoint": {
 
                "serviceName": "service1",
 
                "ipv4": "xxx.xxx.xxx.111"
 
            }
 
        },
 
        {
 
            "key": "http.url",
 
            "value": "/service1",
 
            "endpoint": {
 
                "serviceName": "service1",
 
                "ipv4": "xxx.xxx.xxx.111"
 
            }
 
        }
 
    ]
 
}
 
 
 
# Service2 的span
 
{
 
    "traceId": "daaed0921874ebc3",
 
    "id": "411d4c32c102a974",
 
    "name": "get",
 
    "parentId": "daaed0921874ebc3",
 
    "timestamp": 1476197069806000,
 
    "duration": 1040000,
 
    "annotations": [
 
        {
 
            "timestamp": 1476197069806000,
 
            "value": "sr",
 
            "endpoint": {
 
                "serviceName": "service2",
 
                "ipv4": "xxx.xxx.xxx.112"
 
            }
 
        },
 
        {
 
            "timestamp": 1476197070846000,
 
            "value": "ss",
 
            "endpoint": {
 
                "serviceName": "service2",
 
                "ipv4": "xxx.xxx.xxx.112"
 
            }
 
        }
 
    ],
 
    "binaryAnnotations": [
 
        {
 
            "key": "http.status_code",
 
            "value": "200",
 
            "endpoint": {
 
                "serviceName": "service2",
 
                "ipv4": "xxx.xxx.xxx.112"
 
            }
 
        },
 
        {
 
            "key": "http.url",
 
            "value": "/service2",
 
            "endpoint": {
 
                "serviceName": "service2",
 
                "ipv4": "xxx.xxx.xxx.112"
 
            }
 
        }
 
    ]
 
}
 
 
 
# Service3的span
 
{
 
    "traceId": "daaed0921874ebc3",
 
    "id": "7c0d7d897a858217",
 
    "name": "get",
 
    "parentId": "daaed0921874ebc3",
 
    "timestamp": 1476197071011000,
 
    "duration": 1059000,
 
    "annotations": [
 
        {
 
            "timestamp": 1476197071011000,
 
            "value": "sr",
 
            "endpoint": {
 
                "serviceName": "service3",
 
                "ipv4": "xxx.xxx.xxx.113"
 
            }
 
        },
 
        {
 
            "timestamp": 1476197072070000,
 
            "value": "ss",
 
            "endpoint": {
 
                "serviceName": "service3",
 
                "ipv4": "xxx.xxx.xxx.113"
 
            }
 
        }
 
    ],
 
    "binaryAnnotations": [
 
        {
 
            "key": "http.status_code",
 
            "value": "200",
 
            "endpoint": {
 
                "serviceName": "service3",
 
                "ipv4": "xxx.xxx.xxx.113"
 
            }
 
        },
 
        {
 
            "key": "http.url",
 
            "value": "/service3",
 
            "endpoint": {
 
                "serviceName": "service3",
 
                "ipv4": "xxx.xxx.xxx.113"
 
            }
 
        }
 
    ]
 
}
上一篇 下一篇

猜你喜欢

热点阅读