本篇内容主要讲解“UAVStack中的调用链是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“UAVStack中的调用链是什么”吧!
服务端信息收集
服务端信息收集整体流程如下图所示,通过在应用容器(tomcat等)启动过程中植入切点从而实现在应用逻辑执行之前和之后对请求进行劫持。
应用逻辑执行之前:解析request中调用链信息,并初始化调用链上下文;
应用逻辑执行之后:解析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没有任何关系。它对外提供了四个能力:
doRequest:在所有应用处理请求之前进行劫持;
doResponse:在所有应用处理请求之后进行劫持;
BlockHandlerChain:阻塞自当前handler以后的所有handler,此处的handler为注册在当前;
BlockFilterChain阻塞自当前Filter以后的所有Filter。
调用链借助于GlobalFilterHandler提供的前两个能力,实现了在应用处理请求之前和之后执行调用链逻辑的功能。
轻调用链实现
具体UML图如下:
从UML图中可以清晰地看到, InvokeChainSupporter(调用链实现逻辑入口和调用链所需资源初始化实现类)将中间件增强技术进行了二次增强。它允许使用者在其中注册不同的handler,并且在handler的preCap和doCap(中间件增强技术中的逻辑执行之前和之后的切点术语)方法之前和之后动态织入adapter,从而能够执行更多的定制化适配和个性化逻辑。所有supporter和adapter均采用反射调用方式,最大程度上减少了中间件增强技术的依赖。
有了二次增强技术,我们就可以开始下面的调用链绘制工作了。
轻调用链绘制实现主要依赖于注册在InvokeChainSupporter上的 ServiceSpanInvokeChainHandler。主要绘制过程如下:
解析请求信息,提取其中调用链关心的信息,并将解析出来的信息放入上下文中;
通过解析出来的请求头信息进行逻辑分流,根据不同的协议类型就行不同的逻辑处理;
mq逻辑
http逻辑
dubbo逻辑
初始化调用链上下文,并初始化main span上下文;
在应用处理完请求之后,将调用链信息进行统一输出。
下面来看一下具体每一步都做了什么。
解析请求信息
对于像tomcat这类中间件容器,所有进入tomcat的请求都会被封装成HttpServletRequest和HttpServletResponse(后面简称request和response)最终进入用户的servlet中。调用链借助于中间件增强技术会在用户逻辑处理之前将request和response进行一次拦截,并解析其中是否含有调用链信息。如果有则将调用链信息进行封装放入上下文中。
逻辑分流
由于不同协议对应的调用链绘制逻辑也不同,此处调用链会根据协议类型进行一次分发。
初始化调用链上下文
将调用链上下文中的信息进行解析:
没有父节点则将当前节点当作初始化节点,并初始化记录当前服务内调用链信息的main span;
有父节点则根据父节点信息初始化当前节点,并初始化记录当前服务内调用链信息的main span。
main span:在服务内可能会进行多次客户端通讯或服务间通讯,需要一个main span来记录当前服务内调用链最后一个节点的信息。
调用链信息输出
在用户逻辑处理结束之后,调用链记录器会从上下文中取出当前服务的调用链信息并将其输出到指定日志路径。
服务间上下文传递
到此,相信大家对“UAVStack中的调用链是什么”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。