写点什么

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

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

    阅读完需:约 8 分钟

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

前言


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


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


服务端信息收集


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


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


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


1530500603797023069.png


切点植入


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


1530500626605010636.png


图片来源于网络


在 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 图如下:


1530500673995023331.png


从 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/detail/150


2020-02-14 10:37650

评论

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

聊聊技术人员如何学习成长

架构精进之路

职业成长

在网上被MG坑审过却一直延迟无法取出到账怎么解决 (LGF微7998)

Geek_db0f9e

一套完整的后台管理系统(附源码),非常实用!

程序员生活志

管理系统

云原生在京东丨云原生时代下的监控:如何基于云原生进行指标采集?

京东科技开发者

云原生

mongodb 源码实现、调优、最佳实践系列-百万级代码量mongodb内核源码阅读经验分享

杨亚洲(专注MongoDB及高性能中间件)

MySQL mongodb 源码 中间件 分布式数据库mongodb

一个草根的日常杂碎(10月20日)

刘新吾

随笔杂谈 生活记录 社会百态

央行数字货币离我们还有多远?

CECBC

数字货币

独家!阿里技术人限产的MySQL高级笔记及面试宝典,学完简直开挂

Java架构追梦

Java MySQL 数据库 架构 面试

解锁华为云AI如何助力无人车飞驰“新姿势”,大赛冠军有话说

华为云开发者联盟

AI 无人驾驶

膜拜!阿里技术总监纯手打的《MySQL笔记》内部资料限时分享

Java架构师迁哥

Java程序员还在为没有项目经验感到苦恼?快来看看GitHub上最火的SpringCloud微服务商城系统开源项目,附全套教程!

Java架构之路

Java 程序员 架构 面试 编程语言

1分钟带你入门 React 公共逻辑抽离HOC...

Leo

大前端 React Hooks HOC Render Props

游戏数值策划之常用excel函数

吴优秀同学

Excel 游戏

连续一个月每天加班到凌晨三点,终于把Java程序员必知必会的计算机底层操作系统知识和网络知识整理出来了,已整理成文档!

Java架构之路

Java 程序员 架构 编程语言 操作系统

基于注解的参数校验器Hibernate Validator

HelloLittleRain

Java springboot 参数校验 Hibernate-Validator

华为云瑶光:打通云边端界限,为企业云上业务带来最优解

华为云开发者联盟

华为 云服务

算法分析关键

Geek_0b8195

算法和数据结构

分布式下,我想要一致性

架构师修行之路

分布式 微服务

美腻了!Java资深架构师带你深度学习字节跳动的亿级流量+高并发

Java架构追梦

Java 学习 架构 面试 微服务

一个草根的日常杂碎(10月19日)

刘新吾

随笔杂谈 生活记录 社会百态

Nginx 在运维领域中的应用,看这一篇就够了

华章IT

nginx Linux 运维工程师

利用区块链等技术,加强对交通运输信用信息的归集共享和分析应用

CECBC

区块链 交通运输

1分钟带你入门 Redux 中间件

Leo

大前端 中间件 Redux Redux中间件

透视HTTPS建造固若金汤的堡垒

码哥字节

https 加密解密 HTTP

万物互联的IoT时代,柔性电子会大行其道吗?

脑极体

第四周作业

dll

架构训练营学习笔记之五技术选型(一)

于成龙

架构训练营

一个草根的日常杂碎(10月18日)

刘新吾

随笔杂谈 生活记录 社会百态

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