Zipkin安装和使用

在前面的blog中介绍过apm原理和开源apm框架,这里继续介绍Zipkin的安装使用。
Zipkin官网:https://zipkin.io/pages/quickstart。

前文导航:
分布式跟踪系统选型与实践
Elastic APM安装和使用
Cat的安装和使用


Zipkin服务端部署

根据官网文档,服务端部署有两种方式:
1.Java8及以上版本的,可以直接下载官方包运行:

curl -sSL https://zipkin.io/quickstart.sh | bash -s
java -jar zipkin.jar

2.下载源码自己打包

# get the latest source
git clone https://github.com/openzipkin/zipkin
cd zipkin
# Build the server and also make its dependencies
./mvnw -DskipTests --also-make -pl zipkin-server clean install
# Run the server
java -jar ./zipkin-server/target/zipkin-server-*exec.jar

博主下载的官方包运行后会报错,因此按照第二种方式运行zipkin服务端。

Zipkin使用

官方支持的客户端:
在这里插入图片描述
社区支持的客户端就更多了,几乎主流语言都支持,具体可参见官网:
https://zipkin.io/pages/tracers_instrumentation.html。

下面以python为例说明。环境为:python2.7,使用py_zipkin库。

创建第一个服务:

import time

import requests
from flask import Flask
from flask import request
from py_zipkin.zipkin import zipkin_span, create_http_headers_for_new_span, ZipkinAttrs

app = Flask(__name__)

app.config.update({
    "ZIPKIN_HOST": "127.0.0.1",
    "ZIPKIN_PORT": "9411",
    "APP_PORT": 5000,
})


def do_stuff():
    time.sleep(0.5)
    headers = create_http_headers_for_new_span()
    requests.get('http://localhost:8000/service1/', headers=headers)
    return 'OK'


def http_transport(encoded_span):
    # encoding prefix explained in https://github.com/Yelp/py_zipkin#transport
    # body = b"\x0c\x00\x00\x00\x01"+encoded_span
    body = encoded_span
    zipkin_url = "http://127.0.0.1:9411/api/v1/spans"
    # zipkin_url = "http://{host}:{port}/api/v1/spans".format(
    #   host=app.config["ZIPKIN_HOST"], port=app.config["ZIPKIN_PORT"])
    headers = {"Content-Type": "application/x-thrift"}

    # You'd probably want to wrap this in a try/except in case POSTing fails
    r = requests.post(zipkin_url, data=body, headers=headers)
    print(type(encoded_span))
    print(encoded_span)
    print(body)
    print(r)
    print(r.content)


@app.route('/')
def index():
    with zipkin_span(
            service_name="webapp",
            zipkin_attrs=ZipkinAttrs(
                trace_id=request.headers.get('X-B3-TraceID', None),
                span_id=request.headers.get('X-B3-SpanID', None),
                parent_span_id=request.headers.get('X-B3-ParentSpanID', None),
                flags=request.headers.get('X-B3-Flags', None),
                is_sampled=request.headers.get('X-B3-Sampled', None),
            ),
            span_name='index',
            transport_handler=http_transport,
            port=5000,
            sample_rate=100,  # 0.05, # Value between 0.0 and 100.0
    ) as zipkin_context:
        with zipkin_span(service_name="webapp", span_name='do_stuff'):
            do_stuff()
        print zipkin_context.zipkin_attrs.trace_id
        time.sleep(1)

    return 'OK', 200


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5000, debug=True)

创建第二个服务:

# coding=utf-8
import time

import requests
from flask import Flask
from flask import request
from py_zipkin.zipkin import zipkin_span, ZipkinAttrs

app = Flask(__name__)
app.config.update({
    "ZIPKIN_HOST": "127.0.0.1",
    "ZIPKIN_PORT": "9411",
    "APP_PORT": 8000,
})


def do_stuff():
    time.sleep(0.5)
    with zipkin_span(service_name="service1", span_name='service1_db_search'):
        db_search()
    return 'OK'


def db_search():
    time.sleep(2)
      
def http_transport(encoded_span):
    # encoding prefix explained in https://github.com/Yelp/py_zipkin#transport
    # body = b"\x0c\x00\x00\x00\x01" + encoded_span
    body = encoded_span
    zipkin_url = "http://127.0.0.1:9411/api/v1/spans"
    # zipkin_url = "http://{host}:{port}/api/v1/spans".format(
    #    host=app.config["ZIPKIN_HOST"], port=app.config["ZIPKIN_PORT"])
    headers = {"Content-Type": "application/x-thrift"}

    # You'd probably want to wrap this in a try/except in case POSTing fails
    requests.post(zipkin_url, data=body, headers=headers)


@app.route('/service1/')
def index():
    with zipkin_span(
            service_name="service1",
            zipkin_attrs=ZipkinAttrs(
                trace_id=request.headers.get('X-B3-TraceID', None),
                span_id=request.headers.get('X-B3-SpanID', None),
                parent_span_id=request.headers.get('X-B3-ParentSpanID', None),
                flags=request.headers.get('X-B3-Flags', None),
                is_sampled=request.headers.get('X-B3-Sampled', None),
            ),
            span_name='index_service1',
            transport_handler=http_transport,
            port=8000,
            sample_rate=100,  # 0.05, # Value between 0.0 and 100.0
    ) as zipkin_context:
        with zipkin_span(service_name="service1", span_name='service1_do_stuff'):
            do_stuff()
        print zipkin_context.zipkin_attrs.trace_id
    return 'OK', 200


if __name__ == '__main__':
    app.run(host="0.0.0.0", port=8000, debug=True)

访问http://127.0.0.1:5000/,然后登录zikin后台http://127.0.0.1:9411/可以看到如下界面:

在这里插入图片描述
点击搜索按钮,可以看到调用信息:
在这里插入图片描述
点击show进入调用链路可以看到消息树:
在这里插入图片描述
注意:zipkin版本必须为py_zipkin==0.20.0(ubuntu+python2.7),当使用0.20.1时,部分服务名为显示为UNKNOWN:
在这里插入图片描述

Zipkin存储方式

按照上文的部署,zipkin的数据默认是存在内存中的。重启服务时数据会丢失。下面将存储方式改为mysql。

新建zipkin数据库,在源码的zipkin-storage/mysql-v1/src/main/resources目录下找到sql脚本(https://github.com/openzipkin/zipkin/blob/master/zipkin-storage/mysql-v1/src/main/resources/mysql.sql),执行sql脚本创建好数据表。

启动zipkin服务端时指定数据库参数:

STORAGE_TYPE=mysql MYSQL_USER=root MYSQL_PASS=123456 MYSQL_HOST=127.0.0.1 MYSQL_TCP_PORT=3306 java -jar zipkin-server-*exec.jar

这样埋点数据就会存储到数据库中。zipkin_spans数据如下:
在这里插入图片描述

参考资料:

[1]https://zipkin.io/
[2]https://www.cnblogs.com/xiao987334176/p/12074335.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值