前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >zipkin微服务调用链分析(python)

zipkin微服务调用链分析(python)

作者头像
py3study
发布2020-03-23 17:13:41
1.9K0
发布2020-03-23 17:13:41
举报
文章被收录于专栏:python3python3

一,概述

zipkin的作用

在微服务架构下,一个http请求从发出到响应,中间可能经过了N多服务的调用,或者N多逻辑操作, 如何监控某个服务,或者某个逻辑操作的执行情况,对分析耗时操作,性能瓶颈具有很大价值, zipkin帮助我们实现了这一监控功能。

二、安装zipkin

环境说明

操作系统:centos 7.6

ip:192.168.31.232

配置:2核4g

python版本:3.5.2

启动zipkin

启动方式有2种,一个是docker,一个jar包。任选其一即可。

本文采用jar包方式启动

docker

代码语言:javascript
复制
docker run --name zipkin -d -p 9411:9411 openzipkin/zipkin

jar包

代码语言:javascript
复制
wget https://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server/2.12.9/zipkin-server-2.12.9-exec.jar
java -jar zipkin-server-2.12.9-exec.jar

访问zipkin

代码语言:javascript
复制
http://192.168.31.232:9411

效果如下:

1.png
1.png

三、python实现zipkin

使用py_zipkin模块来实现,这里以flask项目来测试。

安装模块

代码语言:javascript
复制
pip3 install  py_zipkin pymysql flask

创建项目

新建demo.py

代码语言:javascript
复制
mkdir -p /data/flask_demo/cd /data/flask_demo/vim demo.py

内容如下:

代码语言:javascript
复制
import requests
from flask import Flask
from py_zipkin.zipkin import zipkin_span,create_http_headers_for_new_span
import time

app = Flask(__name__)

app.config.update({
    "ZIPKIN_HOST":"127.0.0.1",
    "ZIPKIN_PORT":"9411",
    "APP_PORT":5000,
    # any other app config-y things
})


def do_stuff():
    time.sleep(2)
    headers = create_http_headers_for_new_span()
    requests.get('http://localhost:6000/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',
        span_name='index',
        transport_handler=http_transport,
        port=5000,
        sample_rate=100, #0.05, # Value between 0.0 and 100.0
    ):
        with zipkin_span(service_name='webapp', span_name='do_stuff'):
            do_stuff()
        time.sleep(1)
    return 'OK', 200

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

新建server1.py

代码语言:javascript
复制
from flask import request
import requests
from flask import Flask
from py_zipkin.zipkin import zipkin_span,ZipkinAttrs
import time
import pymysql

app = Flask(__name__)
app.config.update({
    "ZIPKIN_HOST":"127.0.0.1",
    "ZIPKIN_PORT":"9411",
    "APP_PORT":5000,
    # any other app config-y things
})


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


def db_search():
    # 打开数据库连接
    db = pymysql.connect("127.0.0.1", "root", "123456", "mysql", charset='utf8')
    # 使用cursor()方法获取操作游标
    cursor = db.cursor()
    # 使用execute方法执行SQL语句
    cursor.execute("SELECT VERSION()")
    # 使用 fetchone() 方法获取一条数据
    data = cursor.fetchone()
    print("Database version : %s " % data)
    # 关闭数据库连接
    db.close()

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['X-B3-TraceID'],
            span_id=request.headers['X-B3-SpanID'],
            parent_span_id=request.headers['X-B3-ParentSpanID'],
            flags=request.headers['X-B3-Flags'],
            is_sampled=request.headers['X-B3-Sampled'],
        ),
        span_name='index_service1',
        transport_handler=http_transport,
        port=6000,
        sample_rate=100, #0.05, # Value between 0.0 and 100.0
    ):
        with zipkin_span(service_name='service1', span_name='service1_do_stuff'):
            do_stuff()
    return 'OK', 200

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

运行demo.py

代码语言:javascript
复制
python3 demo.py

运行server1.py

代码语言:javascript
复制
python3 server1.py

访问5000端口

1.png
1.png

四、查看调用链

点击查证,点击下面的结果

1.png
1.png

 效果如下:

1.png
1.png

可以看到,有webapp和services两个service,5个span标签,可以清楚看到service和service,service和span,span和span之间的关系,和各span耗时情况。

点击依赖,效果如下:

1.png
1.png

点击webapp,效果如下:

1.png
1.png

五、api调用

官网api文档:https://zipkin.io/zipkin-api/#/default/get_traces

这里演示一下,调用2个api

services

返回与span终结点关联的所有服务名称的列表。

http://192.168.31.232:9411/api/v2/services

 效果如下:

1.png
1.png

traces

 调用此请求将检索与以下筛选器匹配的跟踪。

http://192.168.31.232:9411/api/v2/traces

效果如下:

1.png
1.png

 这里的tags,可以显示错误信息。

有错误时,就是红色的,点击红色区块

1.png
1.png

就可以看到具体信息

1.png
1.png

这个错误信息表示,无法连接到mysql。因为这台机器,还没有mysql服务。

为了消除这个错误,可以再启动一个mysql数据库。

代码语言:javascript
复制
mkdir -p /data/mysql
docker pull mysql:5.7

docker run -itd -p 3306:3306 --name wiki-mysql -e MYSQL_ROOT_PASSWORD=123456 --restart=always --restart=on-failure:1 --oom-score-adj -1000 --privileged=true --log-opt max-size=10m --log-opt max-file=1 -v /data/mysql:/var/lib/mysql  mysql:5.7

重新启动server1.py

再次访问5000端口

1.png
1.png

再次查询一次,就没有红色了

1.png
1.png

如果需要做报警,可以通过调用api,获取到error信息,进行统一的邮件通知。

六、mysql的方式存储

注意:zipkin的数据,默认是存在内存中的,如果重启服务,会造成数据丢失。

在现有数据库基础上,新建实例,实例名为zipkin。

代码语言:javascript
复制
CREATE DATABASE zipkin DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

然后执行官网建库脚本

代码语言:javascript
复制
https://github.com/openzipkin/zipkin/blob/master/zipkin-storage/mysql-v1/src/main/resources/mysql.sql

执行sql之后,会建立3张表

这样我们的数据库就建好了。

执行

代码语言:javascript
复制
STORAGE_TYPE=mysql MYSQL_USER=root MYSQL_PASS=123456 MYSQL_HOST=127.0.0.1 MYSQL_TCP_PORT=3306 java -jar zipkin-server-2.12.9-exec.jar

这样启动zipkin,就自动连上mysql,并存储数据了。

如图,大功告成

1.png
1.png

注意,一般我们都在后台运行zipkin,所以用nohup的方式启动,命令如下

代码语言:javascript
复制
STORAGE_TYPE=mysql MYSQL_USER=root MYSQL_PASS=123456 MYSQL_HOST=127.0.0.1 MYSQL_TCP_PORT=3306 nohup java -jar zipkin-server-2.12.9-exec.jar &

本文参考链接:

https://www.cnblogs.com/shijingjing07/p/9340131.html

https://www.cnblogs.com/tseng-iOS/p/8005889.html

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-03-19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一,概述
    • zipkin的作用
    • 二、安装zipkin
      • 环境说明
        • 启动zipkin
          • docker
          • jar包
        • 访问zipkin
        • 三、python实现zipkin
          • 安装模块
            • 创建项目
            • 四、查看调用链
            • 五、api调用
              • services
                • traces
                • 六、mysql的方式存储
                相关产品与服务
                云数据库 SQL Server
                腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档