写点什么

调用链系列(一):解读 UAVStack 中的贪吃蛇 - 调用链

  • 2020-02-14
  • 本文字数:4289 字

    阅读完需:约 14 分钟

调用链系列(一):解读UAVStack中的贪吃蛇-调用链

背景

对于分布式在线服务,一个请求需要经过多个系统中多个模块,可能多达上百台机器的协作才能完成单次请求。这种场景下单靠人力无法掌握整个请求中各个阶段的性能开销,更无法快速的定位系统中性能瓶颈。当发生故障时通常需要查看大量日志跨越多个团队来确认问题。


举个栗子


程序猿小亮作为一个在职场摸爬滚打多年资深工程师,他可能面临的系统设计是这个样子的,如下图。


1530510490129014217.jpg


图片来自于网络


借助良好的系统设计和编码规范,对于一般有问题的请求处理,小亮依据自己对多个系统的了解通过翻阅大量的日志文件(前提是日志输出也需要规范)花费两个小时来定位到问题。随着用户的不断增长系统复杂度也呈现指数增长,小亮的大部分时间都浪费在了团队沟通之类的工作上。小亮的幸福指数也像系统复杂度一样呈现指数下降。


小亮这时可能会想,要是有一个东西能把每次请求经过的系统都记录下来,要是能把每个节点消耗时间、处理类神马的信息也抓出来那这个世界得多么美好。


一个偶然的机会小亮知道了 UAVStack 其中一个叫做调用链的神奇功能,在对业务代码没有任何侵入的前提下轻松解决了他的难题。下面就让我们一起来开启一段探索 UAVStack 的神奇之旅。


UAVStack 调用链技术栈支持


col 1col 2col 3col 4
技术栈详细技术栈名称支持状态备注
jdk6java原生queue暂不支持
7
8
9
java自定义方法
应用框架Dubbo全量支持
CXF
AXIS2
XFIRE
SUN JAXWS
Jersey
SpringMVC
SpringRESTService
Servlet(2.5/3.x)
Struts 2.x
Wink
Apache HttpClient(同步/异步)
Log4j
LogBack
应用服务器Tomcat(6+)全量支持
SpringBoot(也归为应用服务器)
Jetty(7+)
数据源MySQL全量支持
Oracle等JDBC数据源
MongoDB(MongoClient)
Redis(JEDIS,LETTUCE,ARedis)aredis暂不支持
消息中间件RabbitMQ(消费/生产)全量支持
RocketMQ(消费/生产)即将支持
Kafaka(消费/生产)即将支持
数据库连接池DBCP/2全量支持
c3p0
Druid
Proxool
Hikari
MyBatis CP
Tomcat DBCP/2

效果展示

轻型调用链展示详情:


1530510508608007111.jpg


重调用链开启以后请求报文体抓取视图:


1530510516518003652.jpg


更多使用技巧和说明请参阅官网:https://uavorg.github.io/documents/uavdoc_useroperation/91.html(用户指南中调用链部分)。

具体实现

UAVStack 调用链实现分为模型设计、服务端信息收集(轻/重)、方法级信息收集(轻/重)、客户端信息收集(轻/重)、调用链协议设计(轻/重)、调用链上下文传递、调用信息记录及传递、调用数据统计处理等。由于篇幅限制,本期暂时只分享其中的模型设计及实现调用链模型时序图。

模型设计

借鉴前人经验并揉合具体业务场景需求,抽象出了如下调用链模型:


            调用链元数据:
1)SpanEndpointType:调用类型(Root(“E”),Service(“S”), Client(“C”), Method(“M”));
Root指本条调用链中的第一个节点,即一条调用链的开始位置,可以是一个服务请求,一次httpclient调用等;
Service指当前调用链中非第一个节点且是系统中对外提供的服务,如用户登录服务;
Client指当前调用链中非第一个节点且是当前系统与外部沟通的一种途径,如httpclient、mongoclient等;
Method值当前调用链中非第一个节点且是系统中的一个函数,如日志数出函数等。
2)traceId:调用链唯一标识符;
3)spanId:一条调用链中当前节点的调用顺序(与SpanEndpointType 结合唯一);spanId采用分层设计,形如1.2.1,既能表示调用顺序同时又能反应所才调用链层级;
4)parentId:一条调用链中当前节点的父调用节点。
调用链绘制规则:
1)调用者(服务、web)最初调用(无父调用)记为开始节点E,并生成唯一调用链ID,traceID;
2)系统内应用组件调用(如httpclient,方法调用等),spanId末尾数字加1(若为第一个则末尾加.1);
3)系统间调用(如A服务调用B服务),A服务与B服务span信息只有SpanEndpointType不同(分别对应span的两个端)。
举个栗子
背景介绍:用户小明想通过网络获取一些知识,通过网络他进入了系统O。服务O中部署了服务A和B,A服务使用httpclient与B通讯,B服务先会与redis交互然后和myql交互,最后系统O将小明感兴趣的内容返回给小明;
完成此次请求UAV抽象出如下调用链模型:
1)小明(下图中的调用方)通过门户访问了A服务,此时调用链生成唯一traceId并将当前节点的SpanEndpointType置为N(第一个节点的意思),spanId置为1(当前调用层中的第一个节点),parentId置为E(没有父节点的意思);
2)A服务通过httpclient向B服务发起一次http请求,此时调用链元数据如下traceId(沿用父节点id);1.1(spanId末尾加.1,因为为第一次调用);1(parentId父节点的spanId);C(调用类型记录为C客户端调用);
3)B服务接收到来自于A服务通过httpclient的调用,此时调用链元数据如下traceId(沿用初始调用时id);1.1(spanId沿用传递过来的spanId);1(parentId沿用传递过来的parentId);S(调用类型记录为S服务端处理请求);
4)B服务先查询redis,此时调用链元数据如下traceId(沿用初始调用时id);1.1.1(spanId末尾加.1,因为为第一次调用);1.1(parentId父节点的spanId);C(调用类型记录为C客户端调用);
5)B服务又发起对mysql的查询,此时调用链元数据如下traceId(沿用初始调用时id);1.1.2(spanId末尾数字加1,因为为非第一次调用);1.1(parentId父节点的spanId);C(调用类型记录为C客户端调用);
6)处理结束,调用链将记录的信息进行记录。


![](http://college.creditease.cn/resources/upload/image/20180702/1530510526648078569.png "1530510526648078569.png")
## 调用链时序图


![](http://college.creditease.cn/resources/upload/image/20180702/1530510533318024970.png "1530510533318024970.png")
UAVServer:中间件增强框架,提供在中间件的不同生命周期进行劫持的能力,即中间件劫持技术,如tomcat webcontainer启动开始时刻等;
JEEServiceRunGlobalFilterHandler:借助中间件劫持技术延伸出的全局filter,能够拦截所有经过中间件(tomcat等)的请求;
ServiceSpanInvokeChainHandler:调用链中专注处理归为Service类型节点的handler;
ClientSpanInvokeChainHandler:调用链中专注处理归为Client类型节点的handler;
XXAdapter:泛指调用链中所有的adapter,提供在handler(分为Service、Client、Method三种handler,图中省略了Method类型)执行动作before和after时刻操作数据的能力;


实现对用户代码无任何”侵入”的前提下完成调用链的生成,过程大致分为如下几个过程:
1)在JEEServiceRunGlobalFilterHandler的doRepuest中包装解析请求;
2)xxAdapter中的before对数据进行适配;
3)xxHandler处理对应范围内(Service、Client和Method)内请求数据;
4)xxAdapter中的after对数据进行整理或记录;
5)在JEEServiceRunGlobalFilterHandler的doResponse中返回处理过后请求。
# 总结 </section> </section></section>
复制代码


本文主要目的是让读者对 UAVStack 的调用链有一个整体的认识,初步了解一条调用链绘制的大致生命周期,具体的实现将在以后的分享中详细介绍。


本文转载自宜信技术学院网站。


原文链接:http://college.creditease.cn/detail/149


2020-02-14 10:41946

评论

发布
暂无评论
发现更多内容

安全管理 | 前后端方案详解:Vue/SpringBoot+SpringSecurity+JWT

梁龙先森

大前端 springboot springsecurity JWT 七日更

架构师训练营 1 期 -- 第十三周总结

曾彪彪

极客大学架构师训练营

盘点2020|多线程的遥感大数据行业产品经历

老壳有点爽

大数据 盘点2020 InSAR

扩招1W人,字节跳动内部公开12月份Java岗71道面试题

比伯

Java 编程 架构 面试 程序人生

Tufin联合Cisco,将网络安全自动化进行到底

Geek_448e23

网络安全 自动化管理 云安全

5张图搞懂Java引用拷贝、深拷贝、浅拷贝

bigsai

Java 浅拷贝和深拷贝

forsage以太坊矩阵系统软件开发|forsage以太坊矩阵APP开发

系统开发

波场链智能合约软件系统开发|波场链智能合约APP开发

系统开发

盘点2020 | 微服务架构下该如何技术选型呢?

xcbeyond

微服务 技术选型 盘点2020 选型原则

建议收藏,mybatis插件原理详解

田维常

mybatis

985研究生熬夜23天吃透845页架构宝典 终收割腾讯Java岗offer!再也不用怀疑人生了

比伯

Java 编程 架构 面试 程序人生

警务通APP系统开发,移动警务平台搭建解决方案

t13823115967

智慧城市

干货丨如何使用Redash连接DolphinDB数据源

DolphinDB

数据处理 时序数据库 DolphinDB 数据库开发 redash

女朋友突然问我DNS是个啥....

乱敲代码

计算机网络 DNS DNS服务器

Kafka实战宝典:Kafka的控制器controller详解

数据社

kafka 七日更

微软最强 Python 自动化工具开源了!不用写一行代码!

星安果

Python 开源 自动化 工具 高效率

DAPP软件系统开发

系统开发

边缘计算和5G:我们从何而来?

VoltDB

云计算 大数据 5G 物联网 边缘计算

阅站无数!不过我只推荐下面这些

苹果看辽宁体育

推荐 网站

盘点2020 | 一个三线程序员的2020年,不卑不亢

沉默王二

程序员 盘点2020 沉默王二

PostgreSQL高可用:多主复制解决方案

PostgreSQLChina

数据库 postgresql 开源

架构师 3 期 3 班 -week4- 作业

zbest

作业 week4

程序员因重复记录日志撑爆ELK被辞退!

Java架构师迁哥

从阿里离职后人虚了,头也秃了,就剩这份Java性能优化的PDF了

Java架构追梦

Java 架构 面试 性能优化 并发

架构师 3 期 3 班 -week4- 总结

zbest

总结 week4

测开之数据类型· 第3篇《列表推导式、字典推导式、2种方式创建生成器》

清菡软件测试

测试开发

对于传统供热系统来说,转型智慧供热需要哪些条件?

一只数据鲸鱼

物联网 数据可视化 供暖系统 3D

复盘node项目中遇到的13+常见问题和解决方案

徐小夕

Java node.js 大前端 nodejs

架构师训练营第 1 期第 13 周作业

业哥

智能微卡口监控系统搭建,智慧平安小区建设解决方案

t13823115967

智慧城市

《O2O实战:他们是如何利用互联网的》.pdf

田维常

互联网

调用链系列(一):解读UAVStack中的贪吃蛇-调用链_区块链_李崇_InfoQ精选文章