zipkin微服务调用链分析
Posted xiao987334176
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了zipkin微服务调用链分析相关的知识,希望对你有一定的参考价值。
一,概述
zipkin的作用
在微服务架构下,一个http请求从发出到响应,中间可能经过了N多服务的调用,或者N多逻辑操作,
如何监控某个服务,或者某个逻辑操作的执行情况,对分析耗时操作,性能瓶颈具有很大价值,
zipkin帮助我们实现了这一监控功能。
二、安装zipkin
环境说明
操作系统:centos 7.6
配置:2核4g
python版本:3.5.2
启动zipkin
docker run --name zipkin -d -p 9411:9411 openzipkin/zipkin
访问zipkin
http://192.168.31.232:9411
效果如下:
三、python实现zipkin
使用py_zipkin模块来实现,这里以flask项目来测试。
安装模块
pip3 install py_zipkin pymysql flask
创建项目
新建demo.py
mkdir -p /data/flask_demo/ cd /data/flask_demo/ vim demo.py
内容如下:
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"x0cx00x00x00x01"+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
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"x0cx00x00x00x01" + 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
python3 demo.py
运行server1.py
python3 server1.py
访问5000端口
四、查看调用链
点击查证,点击下面的结果
效果如下:
可以看到,有webapp和services两个service,5个span标签,可以清楚看到service和service,service和span,span和span之间的关系,和各span耗时情况。
点击依赖,效果如下:
点击webapp,效果如下:
五、api调用
官网api文档:https://zipkin.io/zipkin-api/#/default/get_traces
这里演示一下,调用2个api
services
返回与span终结点关联的所有服务名称的列表。
http://192.168.31.232:9411/api/v2/services
效果如下:
traces
调用此请求将检索与以下筛选器匹配的跟踪。
http://192.168.31.232:9411/api/v2/traces
效果如下:
这里的tags,可以显示错误信息。
有错误时,就是红色的,点击红色区块
就可以看到具体信息
这个错误信息表示,无法连接到mysql。因为这台机器,还没有mysql服务。
为了消除这个错误,可以再启动一个mysql数据库。
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端口
再次查询一次,就没有红色了
注意:zipkin的数据,默认是存在内存中的,如果重启服务,会造成数据丢失。
如果需要存储到mysql中,请参考链接:
https://www.cnblogs.com/tseng-iOS/p/8005889.html
如果需要做报警,可以通过调用api,获取到error信息,进行统一的邮件通知。
本文参考链接:
https://www.cnblogs.com/shijingjing07/p/9340131.html
以上是关于zipkin微服务调用链分析的主要内容,如果未能解决你的问题,请参考以下文章
spring cloud 学习 - sleuth & zipkin 调用链跟踪
Spring Cloud 整合分布式链路追踪系统Sleuth和ZipKin实战,分析系统瓶颈