2025 AI基础设施风向标,不看必后悔!#AI基础设施峰会 了解详情
写点什么

调用链系列(一):解读 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:41989

评论

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

保姆级教程:Redis主从复制原理及集群搭建

小曾同学.com

redis主从 redis哨兵集群 redis 底层原理 redis主从集群 redis数据同步原理

斯坦福 AI 团队被曝抄袭中国大模型开源成果;Zoom 创始人谈视频会议未来丨 RTE 开发者日报 Vol.218

声网

你还不懂区块链就out了

区块链开发团队DappNetWork

生成式 AI 码力全开,动手搭建未来商城

亚马逊云科技 (Amazon Web Services)

Serverless

面试官:说说Netty对象池的实现原理?

王磊

Java

NFTScan 获 Google Cloud 战略支持!

NFT Research

Google Cloud NFT\ NFTScan

1688批量自动下单接口丨1688代采系统丨1688跨境代采系统

tbapi

1688批量采购 1688代购系统

扫码报名活动时,如何避免重复报名?

草料二维码

二维码 活动报名 草料二维码

对象业务的追加写接口

不在线第一只蜗牛

对象 业务开发

研发提效:想快速定制一个OLAP应用?你可以这么做!

京东零售技术

架构 后端 研发提效 企业号 6 月 PK 榜

Stable diffusion采样器详解

程序那些事

程序那些事 Stable Diffusion

用Python打造你的微博热搜追踪器

我再BUG界嘎嘎乱杀

Python 后端 开发语言

告别繁琐,一键同步!聚道云助力企业人力资源大升级

聚道云软件连接器

案例分享

利用Python调用KimiGPT API接口

我再BUG界嘎嘎乱杀

Python 后端 开发语言 GPT

用这个方法给苹果电脑清理app垃圾,让电脑快如闪电

阿拉灯神丁

CleanMyMac Mac 系统 苹果软件 杀毒软件

“码”力全开!高效开发就靠这款神器

ZEGO即构

UI 自定义组件 即构UIkits UIKits

降本增效下的自动化测试实践

老张

软件测试 研发效能 自动化测试 质量保障

RESTful API 设计原则:优化您的接口设计

Liam

后端 Rest API APi设计 REST API

Python高频面试题解析公开课

测吧(北京)科技有限公司

测试

仓库数据同步难题如何轻松破解?

聚道云软件连接器

案例分享

软件测试公开课 | Python高频面试题解析公开课

测试人

软件测试

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