WeClient請求適配
本文主要是對WeClient適配過程的一個(gè)總結(jié)尖坤,適配思路和注意點(diǎn)記錄下來,以便后續(xù)開發(fā)锥忿。
1. 澄清需求
1.1. 需求描述
需要添加一個(gè)適配Springflux框架中的webClient季惩,上報(bào)其請求相關(guān)調(diào)用鏈路以及參數(shù)。
1.2. 需求環(huán)境
webClient是Spring5框架相關(guān)的伊磺,jdk環(huán)境適配環(huán)境為:1.8及以上
使用依賴包:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
1.3. 需求詳情及基礎(chǔ)了解
WebClient是從Spring WebFlux 5.0版本開始提供的一個(gè)非阻塞的基于響應(yīng)式編程的進(jìn)行Http請求的客戶端工具。它的響應(yīng)式編程的基于Reactor的删咱。WebClient中提供了標(biāo)準(zhǔn)Http請求方式對應(yīng)的get屑埋、post、put痰滋、delete等方法摘能,可以用來發(fā)起相應(yīng)的請求。
可以參考HttpClient相關(guān)代碼去獲取對應(yīng)的信息敲街。
2. 適配開發(fā)思路
- 構(gòu)建兩個(gè)類InboundWrapper团搞、InboundWrapper 分別去獲取請求頭(header)信息以及響應(yīng)信息,這兩個(gè)類分別實(shí)現(xiàn)InboundHeaders多艇、InboundWrapper逻恐,使用裝飾器模式,去包裝源碼框架中包含請求頭信息和響應(yīng)信息的類峻黍。
- 找要適配的框架中執(zhí)行發(fā)出請求的真正方法以及能夠獲取到請求頭信息的和響應(yīng)信息的類复隆。webClient框架中發(fā)出請求的入口只有一個(gè),就是RequestHeadersSpec.exchange()
- 整體插碼結(jié)構(gòu)如下圖所示 2-3:
圖2-3:
步驟四(核心):
插碼的邏輯:
1.獲取trace跟蹤,跟蹤方法,需要方法的類的字節(jié)碼
ExitTracer tracer = AgentBridge.instrumentation.createTracer(this, WebClientUtils.exchangeMethod, null, TracerFlags.BACKEND_CALL | TracerFlags.LEAF);
2.獲取跨容器狀態(tài)
CrossProcessState crossProcessState = AgentBridge.getAgent().getCrossProcessState();
3.上報(bào)后端請求信息(tracer矾湃、當(dāng)前調(diào)用鏈路(URI)信息)
WebClientUtils.report((BackendCall) tracer, brURI);
4.記錄跨容器信息、trace信息
WebClientUtils.processOutboundHeader(crossProcessState, (BackendCall) tracer, (WebClient.RequestHeadersSpec) this);
5: 執(zhí)行源代碼邏輯
6.結(jié)束Trace探測
7.上報(bào)響應(yīng)的信息
WebClientUtils.processResponse(crossProcessState, (BackendCall) tracer, response.block());
-
trace返回 return;
if (tracer != null) { tracer.finish(177/* RETURN */, response); }
返回源代碼方法返回的值或者void
上報(bào)后端調(diào)用鏈路邏輯
注意(webClient 框架一般是記錄http或者h(yuǎn)ttps)
拼接訪問uri以及協(xié)議類型后,上報(bào)記錄到trace
BackendCallParameter becp =
BackendCallParameter.create(Backend.createBackend(BackendType.BACKEND_TYPE_HTTP, "HTTP", host, port, connURL), uri, uri);
backendCallTracer.reportBackendCall(becp);
把調(diào)用uri以及適配的類型加入到HTTP_URL矮男、COMPONENT
執(zhí)行響應(yīng)信息處理
判斷是否有響應(yīng)
-
記錄響應(yīng)狀態(tài)
- 小于400猪瞬,則正常返回幌甘。 設(shè)置狀態(tài)碼http.status_code :
-
構(gòu)建該類 InboundWrapper進(jìn)行包裝鞍泉。獲取響應(yīng)的請求頭,判斷
- 解析服務(wù)端返回得響應(yīng)頭
?
執(zhí)行請求頭信息處理
解析請求端的請求頭。
3. 遇到的問題
1. 對webClient框架沒接觸過睦刃,不夠了解其原理以及使用砚嘴。
2. 不熟悉使用,寫代碼時(shí)眯勾,對于代碼調(diào)用的邏輯考慮不夠枣宫,導(dǎo)致寫代碼時(shí)考慮的可能導(dǎo)致問題的點(diǎn)不夠。
3. 對于插碼@BrWeave的使用還需要更深入的理解和多閱讀server源碼吃环。
4. 沒有考慮線程安全并發(fā)修改的問題也颤,導(dǎo)致阻塞在一個(gè)uri的獲取上時(shí)間很久。
5. 測試項(xiàng)目沒有相關(guān)代碼郁轻,需自己重新搭建一個(gè)翅娶。
6. 查找webClient項(xiàng)目源代碼,并找到相關(guān)入口好唯。
- 壓測遇到的問題竭沫。
- agent日志查找是否weave,插碼骑篙、打印等相關(guān)問題蜕提。
4.遇到問題的解決
網(wǎng)站找最好官網(wǎng)去找例子,以及相關(guān)資料靶端。
可以去gitlab上面找已經(jīng)部署的項(xiàng)目使用webClient的例子谎势,熟悉webClient相關(guān)的使用凛膏,思考編寫時(shí)需要注意的問題。
對閱讀關(guān)于@BrWeave的使用脏榆,平時(shí)多看看項(xiàng)目代碼猖毫。
因?yàn)榫帉懙氖翘峁┓剑枰紤]一些線程安全的情況须喂。
在github上面查找吁断。
在官網(wǎng)下載源代碼以及相關(guān)依賴。
開發(fā)完需要多多進(jìn)行多種調(diào)用場景的壓測坞生。
借此多熟悉日志的使用仔役,可以查看該項(xiàng)目下apm_proto 去找對應(yīng)的信息打印。
建議的開發(fā)思路
- 先去找找server項(xiàng)目中是否有類似的例子或者同產(chǎn)品中的源代碼是己,理解相關(guān)的插碼思路骂因。
- 熟悉要開發(fā)或者要適配的框架,相關(guān)原理以及使用例子赃泡。
- 編寫前寒波,先把整體適配邏輯寫出來。
- 找要適配的框架的要進(jìn)行插碼的入口以及需要或許相關(guān)信息的入口
- 整合起來后升熊,把整體思路在理一遍俄烁,進(jìn)行編寫。
- 開發(fā)完级野,在測試項(xiàng)目中進(jìn)行跑一遍页屠,同時(shí)壓測下。在agent日志以及測試平臺(tái)查看相關(guān)打印信息蓖柔。
- 整理相關(guān)報(bào)告辰企。
最重要的還是復(fù)盤: 提高開發(fā)效率。