WeClient请求适配
本文主要是对WeClient适配过程的一个总结,适配思路和注意点记录下来,以便后续开发。
1. 澄清需求
1.1. 需求描述
需要添加一个适配Springflux框架中的webClient,上报其请求相关调用链路以及参数。
1.2. 需求环境
webClient是Spring5框架相关的,jdk环境适配环境为:1.8及以上
使用依赖包:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
1.3. 需求详情及基础了解
WebClient是从Spring WebFlux 5.0版本开始提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具。它的响应式编程的基于Reactor的。WebClient中提供了标准Http请求方式对应的get、post、put、delete等方法,可以用来发起相应的请求。
可以参考HttpClient相关代码去获取对应的信息。
2. 适配开发思路
- 构建两个类InboundWrapper、InboundWrapper 分别去获取请求头(header)信息以及响应信息,这两个类分别实现InboundHeaders、InboundWrapper,使用装饰器模式,去包装源码框架中包含请求头信息和响应信息的类。
- 找要适配的框架中执行发出请求的真正方法以及能够获取到请求头信息的和响应信息的类。webClient框架中发出请求的入口只有一个,就是RequestHeadersSpec.exchange()
- 整体插码结构如下图所示 2-3:
图2-3:
补充说明: 正常在入口类都会有请求头等,响应信息的入参。webClient封装的比较特殊,需要在这两个类中获取到对应的uri入口信息。 这里我们可以看到了,所以我们在OutboundWrapper类中获取请求头信息的包装类就是WebClient$RequestHeadersSpec。
步骤四(核心):
插码的逻辑:
1.获取trace跟踪,跟踪方法,需要方法的类的字节码
ExitTracer tracer = AgentBridge.instrumentation.createTracer(this, WebClientUtils.exchangeMethod, null, TracerFlags.BACKEND_CALL | TracerFlags.LEAF);
2.获取跨容器状态
CrossProcessState crossProcessState = AgentBridge.getAgent().getCrossProcessState();
3.上报后端请求信息(tracer、当前调用链路(URI)信息)
WebClientUtils.report((BackendCall) tracer, brURI);
4.记录跨容器信息、trace信息
WebClientUtils.processOutboundHeader(crossProcessState, (BackendCall) tracer, (WebClient.RequestHeadersSpec) this);
5: 执行源代码逻辑
6.结束Trace探测
7.上报响应的信息
WebClientUtils.processResponse(crossProcessState, (BackendCall) tracer, response.block());
-
trace返回 return;
if (tracer != null) { tracer.finish(177/* RETURN */, response); }
-
返回源代码方法返回的值或者void
上报后端调用链路逻辑
注意(webClient 框架一般是记录http或者https)
拼接访问uri以及协议类型后,上报记录到trace
BackendCallParameter becp =
BackendCallParameter.create(Backend.createBackend(BackendType.BACKEND_TYPE_HTTP, "HTTP", host, port, connURL), uri, uri);
backendCallTracer.reportBackendCall(becp);
把调用uri以及适配的类型加入到HTTP_URL、COMPONENT
执行响应信息处理
-
判断是否有响应
-
记录响应状态
- 小于400,则正常返回。 设置状态码http.status_code :
-
构建该类 InboundWrapper进行包装。获取响应的请求头,判断
- 解析服务端返回得响应头
执行请求头信息处理
解析请求端的请求头。
3. 遇到的问题
1. 对webClient框架没接触过,不够了解其原理以及使用。
2. 不熟悉使用,写代码时,对于代码调用的逻辑考虑不够,导致写代码时考虑的可能导致问题的点不够。
3. 对于插码@BrWeave的使用还需要更深入的理解和多阅读server源码。
4. 没有考虑线程安全并发修改的问题,导致阻塞在一个uri的获取上时间很久。
5. 测试项目没有相关代码,需自己重新搭建一个。
6. 查找webClient项目源代码,并找到相关入口。
- 压测遇到的问题。
- agent日志查找是否weave,插码、打印等相关问题。
4.遇到问题的解决
-
网站找最好官网去找例子,以及相关资料。
-
可以去gitlab上面找已经部署的项目使用webClient的例子,熟悉webClient相关的使用,思考编写时需要注意的问题。
-
对阅读关于@BrWeave的使用,平时多看看项目代码。
-
因为编写的是提供方,需要考虑一些线程安全的情况。
-
在github上面查找。
-
在官网下载源代码以及相关依赖。
-
开发完需要多多进行多种调用场景的压测。
-
借此多熟悉日志的使用,可以查看该项目下apm_proto 去找对应的信息打印。
建议的开发思路
- 先去找找server项目中是否有类似的例子或者同产品中的源代码,理解相关的插码思路。
- 熟悉要开发或者要适配的框架,相关原理以及使用例子。
- 编写前,先把整体适配逻辑写出来。
- 找要适配的框架的要进行插码的入口以及需要或许相关信息的入口
- 整合起来后,把整体思路在理一遍,进行编写。
- 开发完,在测试项目中进行跑一遍,同时压测下。在agent日志以及测试平台查看相关打印信息。
- 整理相关报告。
最重要的还是复盘: 提高开发效率。
网友评论