前言

上篇文章分享了一下调用链的模型设计及模型时序图。相信大家通过上一篇文章对调用链有了一个整体上的了解,如:调用链是什么、能做什么及整体实现策略。

这篇文章我们继续介绍调用链的服务端信息收集以及服务间上下文传递。

服务端信息收集

服务端信息收集整体流程如下图所示,通过在应用容器(tomcat等)启动过程中植入切点从而实现在应用逻辑执行之前和之后对请求进行劫持。

l  应用逻辑执行之前:解析request中调用链信息,并初始化调用链上下文;

l  应用逻辑执行之后:解析response中调用链信息,并将本次请求处理的所有调用链信息输出到日志文件。

切点植入

在介绍切点之前我们应该对servlet容器(本文以tomcat为例)处理一次请求的大致流程有一个整体的了解。

图片来源于网络

在Connector接收到一次连接并转化成请求(Request)后,会将请求传递到Engine的管道(Pipeline)的阀(ValveA)中。请求在Engine的管道中会传递到Engine Valve这个阀中。接着请求会从Engine Valve传递到一个Host的管道中,在该管道中传递到Host Valve这个阀里。接着从Host Valve传递到一个Context的管道中,在该管道中传递到Context Valve中。接下来请求会传递到Wrapper C内的管道所包含的阀Wrapper Valve中,在这里会经过一个过滤器链(Filter Chain),最终送到一个Servlet中。借助于tomcat的这种架构设计,我们可以通过在tomcat处理一次请求的生命周期过程中植入自己的逻辑,将tomcat对外提供的能力进行一次增强,即UAV的中间件增强技术。

中间件增强技术除了巧妙运用了tomcat容器的架构设计之外还借助了java Instrumentation(它给我们提供了一种能够在对象第一次加载时动态修改字节码的能力,由于篇幅原因在此不进行详细讲解,不明白的小伙伴自行查阅资料)。在UAV中通过UAVServer对外提供各种切点能力。

有了中间件增强技术,在应用逻辑执行之前和之后的切点就有了,接下来就是在这些切点位置执行我们自己的调用链逻辑了。

中间件增强技术在调用链中的使用

上文介绍的间件增强技术是一种通过使用javaagent方式动态地在tomcat代码中植入切点代码并以UAVServer的形式对外提供能力的框架(具体能力后续文章会详细介绍)。轻调用链实现正是使用了UAVServer对外提供的GlobalFilterHandler能力。

GlobalFilterHandler: 这里的GlobalFilterHandler是中间件增强技术中的一种能力,与传统的filter没有任何关系。它对外提供了四个能力:

1、 doRequest:在所有应用处理请求之前进行劫持;

2、 doResponse:在所有应用处理请求之后进行劫持;

3、 BlockHandlerChain:阻塞自当前handler以后的所有handler,此处的handler为注册在当前;

4、 BlockFilterChain阻塞自当前Filter以后的所有Filter。

调用链借助于GlobalFilterHandler提供的前两个能力,实现了在应用处理请求之前和之后执行调用链逻辑的功能。

轻调用链实现

具体UML图如下:

从UML图中可以清晰地看到, InvokeChainSupporter(调用链实现逻辑入口和调用链所需资源初始化实现类)将中间件增强技术进行了二次增强。它允许使用者在其中注册不同的handler,并且在handler的preCap和doCap(中间件增强技术中的逻辑执行之前和之后的切点术语)方法之前和之后动态织入adapter,从而能够执行更多的定制化适配和个性化逻辑。所有supporter和adapter均采用反射调用方式,最大程度上减少了中间件增强技术的依赖。

有了二次增强技术,我们就可以开始下面的调用链绘制工作了。

轻调用链绘制实现主要依赖于注册在InvokeChainSupporter上的ServiceSpanInvokeChainHandler。主要绘制过程如下:

1、 解析请求信息,提取其中调用链关心的信息,并将解析出来的信息放入上下文中;

2、 通过解析出来的请求头信息进行逻辑分流,根据不同的协议类型就行不同的逻辑处理;

l  mq逻辑

l  http逻辑

l  dubbo逻辑

3、初始化调用链上下文,并初始化main span上下文;

4、 在应用处理完请求之后,将调用链信息进行统一输出。

下面来看一下具体每一步都做了什么。

解析请求信息

对于像tomcat这类中间件容器,所有进入tomcat的请求都会被封装成HttpServletRequest和HttpServletResponse(后面简称request和response)最终进入用户的servlet中。调用链借助于中间件增强技术会在用户逻辑处理之前将request和response进行一次拦截,并解析其中是否含有调用链信息。如果有则将调用链信息进行封装放入上下文中。

逻辑分流

由于不同协议对应的调用链绘制逻辑也不同,此处调用链会根据协议类型进行一次分发。

初始化调用链上下文

将调用链上下文中的信息进行解析:

1、没有父节点则将当前节点当作初始化节点,并初始化记录当前服务内调用链信息的main span;

2、有父节点则根据父节点信息初始化当前节点,并初始化记录当前服务内调用链信息的main span。

main span:在服务内可能会进行多次客户端通讯或服务间通讯,需要一个main span来记录当前服务内调用链最后一个节点的信息。

调用链信息输出

在用户逻辑处理结束之后,调用链记录器会从上下文中取出当前服务的调用链信息并将其输出到指定日志路径。

服务间上下文传递

对于不同协议调用链传递信息方式也略有不同,具体实现方式借助了中间件增强技术提供的另一个能力:AppFrkHook(简称hook,此功能在客户端调用链实现时会进行具体介绍)。它能够对用户使用的客户端技术进行劫持,如用户使用了httpclient进行通讯,则对httpclient进行劫持并动态织入代码,从而达到在http通讯的过程中注入调用链上下文信息的效果。目标服务在解析请求信息时,将调用链上下文进行解析;在初始化调用链上下文逻辑时,使用传递过来的信息初始化目标服务的调用链上下文,实现跨系统调用时调用链连接。

总结

读完本文之后读者应该对中间件增强技术的实现有了一个大概的了解,并且对其提供的GlobalFilterHandler能力有了一定的认识。对于调用链应明白了服务端和服务间调用链的绘制全过程。

宜信技术学院:http://college.creditease.cn/

调用链系列(二):解读UAVStack中的贪吃蛇-调用链相关推荐

  1. 区块链系列教程之:比特币中的网络和区块链

    文章目录 简介 比特币的网络 网络发现与同步 SPV节点 区块链头 Merkle Tree 比特币中的区块链 区块标识符 创世区块 总结 简介 比特币的底层就是区块链技术,区块链也是因为比特币而广为人 ...

  2. request中的内容存储_宜信开源|调用链系列(3):解读UAVStack中的调用链技术...

    拓展阅读:宜信开源|调用链系列(1):解读UAVStack中的贪吃蛇 调用链系列(二):解读UAVStack中的贪吃蛇-调用链 在Java中,HTTP协议的请求/响应模型是由Servlet规范+Ser ...

  3. 在HTML中制作贪吃蛇游戏

    1.设置盒子来装下整个游戏的外框架与初始界面(一个大的父盒子里面装着两个小盒子一个装游戏框架一个装开始暂停按钮) 2.window.onload = function ()(在浏览器加载完毕后所执行调 ...

  4. 区块链系列教程之:比特币中的共识

    文章目录 简介 比特币中的共识 交易的校验 区块的构建 区块的校验 区块链的分叉 区块链分叉的种类 总结 简介 在比特币的P2P网络中是怎么达成共识的呢?达成共识需要做哪些交易的校验呢?交易和区块是怎 ...

  5. 区块链系列教程之:比特币中的挖矿

    文章目录 简介 比特币的节点构造 挖矿 挖矿节点 创币交易 矿池收入分配 挖矿方向 算力浪费 算力调整 总结 简介 我们知道比特币就是挖矿产生的,那么在比特币网络中,挖矿有什么特点呢?怎么分配挖矿收入 ...

  6. 帝国php调用文章列表,帝国CMS模板中:使用php调用最新文章的代码(非灵动和万能标签)...

    在帝国CMS模板制作中经常遇到想灵活实现效果的地方,比如跨表,结合判断等复杂调用.使用万能标签和灵动标签不足以满足要求的情况下就只能使用PHP的方法来实现!具体代码如下: $w_query=" ...

  7. C语言中通过函数指针调用函数

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 一.函数指针P调用函数max 二.函数中的形参和实参 1.形参 2.实参 3.举例 提示:以下是本篇文章正文内容,下面案例可 ...

  8. 汇编语言贪吃蛇、俄罗斯方块双任务设计实现详解(二)——贪吃蛇详细设计

    详细设计: 2.贪吃蛇详细设计: 如下图所示左下角为主程序对贪吃蛇相关子程序的调用,程序中init_left_window子程序功能为将左侧窗口非边框部分置为空.左边上侧和右侧是贪吃蛇段中,贪吃蛇程序 ...

  9. PHP获取二维数组中某一列的值集合

    PHP还是比较常用的,于是我研究了一下PHP二维数组,下面通过本文给大家介绍PHP获取二维数组中某一列的值集合,对php数组二维数组的值相关知识感兴趣的朋友一起学习吧 PHP还是比较常用的,于是我研究 ...

最新文章

  1. 计算机平均数的函数,Excel2010
  2. Java 缓冲流简介及简单用法
  3. .class文件格式(java字节码文件的格式)
  4. 计算方法太牛了,留着以后教孩子!!!
  5. Android8.0(34)----Android 8.0 Settings流程分析与变动
  6. 驱动编程class_create说明
  7. mybatis 自定义插件的使用
  8. Gephi初识之简单绘图学习
  9. Redisson 3.13.6 发布,官方推荐的 Redis 客户端
  10. hbase put 写入数据慢_HBase运维 | HBase 疑难杂症诊治
  11. arcgis建立拓扑关系
  12. matlab插值函数 外插,Matlab数据插值-内插、外插
  13. 猜价格游戏c语言课程设计,肿么用C#编写一个猜价格的小程序?
  14. iPhone 12 Pro搭载的LiDAR镜头与ToF镜头区别在哪里
  15. 办公室装修设计6大规范示意
  16. Web前端持续集成方案(四)
  17. p95、p99、p999 什么意思
  18. (三)航空发动机强度与振动复习纲要
  19. oracle请求输出全部都是fndwrr,oracle ebs系统维护技巧汇总
  20. The Devil Wears Prada-10

热门文章

  1. mysql设置文本域边框_HTML textarea标签(文本域)
  2. 刘德华被警方传讯 竟在派出所内“顺走”警察手机
  3. 【已解决】有关 xmind 8 U9 序列号一直失效的问题
  4. 2022-2028年中国女性卫生用品行业市场调查研究及未来趋势预测报告
  5. 三、键盘检测原理及应用实现
  6. 模拟商场优惠打折 华为OD真题 100
  7. 计算机技术培训心得400,某某某参加计算机培训心得体会精选(整理版)
  8. 清华博导的“好学生”自述:我为什么逃离科研,选择去中学当老师!
  9. 洗煤厂数字孪生三维可视化平台_洗煤厂webgl大屏可视化管理系统
  10. amqp协议java_AMQP协议介绍