『互聯(lián)網(wǎng)架構(gòu)』dubbo 調(diào)用埋點(diǎn)(114)

原創(chuàng)文章,歡迎轉(zhuǎn)載。轉(zhuǎn)載請(qǐng)注明:轉(zhuǎn)載自IT人故事會(huì),謝謝!
原文鏈接地址:『互聯(lián)網(wǎng)架構(gòu)』dubbo 調(diào)用埋點(diǎn)(114)

上邊幾次都是說的單體的攔截埋點(diǎn),應(yīng)用的內(nèi)部進(jìn)行的,很多的情況系統(tǒng)都是分布式的,怎么去監(jiān)聽RPC(遠(yuǎn)程過程調(diào)用),dubbo,RMI,springcloud,http。只要遠(yuǎn)程調(diào)用,跨進(jìn)程調(diào)用都屬于RPC,也不可能所有的能都涉及到,很多公司都有自己的封裝,例如阿里的HFS,這次只針對(duì)dubbo這種RPC進(jìn)行調(diào)用。
源碼:https://github.com/limingios/netFuture/tree/master/源碼/『互聯(lián)網(wǎng)架構(gòu)』調(diào)?鏈系統(tǒng)工程結(jié)構(gòu)(111)

(一)Dubbo執(zhí)行過程

對(duì)于dubbo的埋點(diǎn),首先要了解dubbo的執(zhí)行過程

節(jié)點(diǎn) 角色說明
Provider 暴露服務(wù)的服務(wù)提供方
Consumer 調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方
Registry 服務(wù)注冊(cè)與發(fā)現(xiàn)的注冊(cè)中心
Monitor 統(tǒng)計(jì)服務(wù)的調(diào)用次數(shù)和調(diào)用時(shí)間的監(jiān)控中心
Container 服務(wù)運(yùn)行容器
  • Dubbo調(diào)用過程


  • 消費(fèi)者調(diào)用過程


(二)調(diào)用端埋點(diǎn)實(shí)現(xiàn)

  • 埋點(diǎn)目的
    1.捕捉消費(fèi)者調(diào)用信息(遠(yuǎn)程接口、URL、參數(shù)、用時(shí)、返回結(jié)果、異常)
    2.傳遞TraceRequest

  • 調(diào)用信息模型表結(jié)構(gòu)

名稱 類型 描述
servicePath string 服務(wù)路徑
serviceName string 服務(wù)
inParam json 返回結(jié)果
outParam json 返回結(jié)果
ErrorMessage string 異常信息
ErrorStack text 異常堆棧
ResultState string 執(zhí)行狀態(tài)
beginTime date 開始時(shí)間
endTime date 結(jié)束時(shí)間
addressIp string 遠(yuǎn)程IP
fromIp string 調(diào)用者IP
  • 埋點(diǎn)位置

如何才能完整的捕捉到以上信息呢?那么就需要了解Dubbo內(nèi)部的調(diào)用
1.分解調(diào)用過程為多個(gè)步驟。
2.這些步驟分別是在哪些協(xié)作線程上完成的?
3.經(jīng)過了哪些方法?
4.經(jīng)過了哪些過濾器?

  • 調(diào)用過程分解&線程協(xié)作


  1. 選擇斷點(diǎn)位置Debug調(diào)試調(diào)用過程
  2. 消費(fèi)者調(diào)用線程源碼分析:


  • 經(jīng)過對(duì)源碼的分析,埋點(diǎn)的位置如下:
    DubboInvoker.doInvoke()
    FutureFilter.invoke()
    DubboInvoker.doInvoke() 方法最靠近調(diào)用方,異常捕捉范圍較大,但是該位置無法通過Attachment 向下傳遞TraceRequest 參數(shù),所以需要FutureFilter.invoke() 進(jìn)行補(bǔ)充,其具體分工如下:
    ·1.DubboInvoker.doInvoke捕獲如下信息: 1、開始時(shí)間 2、服務(wù)路徑 3、服務(wù)方法 4、輸入?yún)?shù) 5、異常信息 6、本地地址
    2.FutureFilter.invoke 基于Attachment 向下傳遞參數(shù) 2、異常信息與堆棧 3、返回結(jié)果

DubboInvoker.doInvoke攔截源碼參見 :com.cbt.agent.collects.dubbo.DubboConsumerRpcExceptionMonitorHandle#invokerBefore

FutureFilter.invoke攔截源碼參見 :
com.cbt.agent.collects.dubbo.DubboConsumerMonitorHandle#invokerBefore

(三)調(diào)用端埋點(diǎn)實(shí)現(xiàn)

  • 埋點(diǎn)目的
    接收TraceRequest信息 ,并創(chuàng)建會(huì)話
  • 埋點(diǎn)位置:
    相對(duì)調(diào)用廣方接收方埋點(diǎn)目的較簡(jiǎn)單,但同樣需分析源碼找準(zhǔn)埋點(diǎn)位置
  • 提供者處理線程分析


經(jīng)分析埋點(diǎn)位置選在離實(shí)際調(diào)用方法較遠(yuǎn)的EchoFilter過濾器理由是捕捉的信息更全面。

具體會(huì)話開啟過程:

  1. 基于Attachment獲取TraceId、ParentId、TraceProperties。
  2. 封裝TraceRequest ,并此為參數(shù)開啟會(huì)話。
  3. 在調(diào)用結(jié)束時(shí)關(guān)閉會(huì)話。
    具體源碼參見:com.cbt.agent.collects.dubbo.DubboProviderMonitorHandle#invokerBefore

(二)Servlet處理埋點(diǎn)

  • Servlet埋點(diǎn)目的
    1.生成TraceId
    2.開啟關(guān)閉監(jiān)控會(huì)話
    3.捕捉Http請(qǐng)求(url、客戶端IP、參數(shù)、響應(yīng)時(shí)長(zhǎng)、響應(yīng)狀態(tài)碼)

  • 埋點(diǎn)埋在哪?
    1.每一個(gè)Control方法
    2.DispatcherServlet.doDispatch方法
    3.HttpServlet.service 方法

  • 方案對(duì)比

方案 優(yōu)點(diǎn) 缺點(diǎn)
應(yīng)用層Control類 簡(jiǎn)單,風(fēng)險(xiǎn)因素低 判別成本高,有局限性,只能根據(jù) HttpServlet 子類或@RequestMapping進(jìn)行識(shí)別。
DispatcherServlet.doDispatch 簡(jiǎn)單,適應(yīng)性強(qiáng) 1、只能針對(duì)spring mvc 項(xiàng)目 2、spring boot 項(xiàng)目不支持
HttpServlet.service 適應(yīng)性強(qiáng),與應(yīng)用層和框架無關(guān) 1、不同的容器ClassPath不一樣,存在兼容性問題。 2、存在風(fēng)險(xiǎn),幾乎所有請(qǐng)求都會(huì)經(jīng)過此方法 3、業(yè)務(wù)異常無法捕獲

總合比較還是選擇 HttpServlet.service 會(huì)更好些。

  • HttpServlet.service 埋點(diǎn)需要做的工作:
    1.字節(jié)碼插樁
    2.請(qǐng)求攔截并獲取請(qǐng)求信息

  • 字節(jié)碼插樁流程

字節(jié)碼插是指在數(shù)據(jù)裝載前在HttpServlet.service 插入監(jiān)控指令,以攔截Http請(qǐng)求,其插樁的過程。

請(qǐng)求攔截是指具體Http請(qǐng)求過來時(shí)進(jìn)行攔截過濾,這么做主要是為了完成兩個(gè)目的

1.開啟監(jiān)控會(huì)話
2.開啟對(duì)Servlet響應(yīng)過程的監(jiān)控

(三)Redis 調(diào)用埋點(diǎn)

  • 埋點(diǎn)可選方案
方案 優(yōu)點(diǎn) 缺點(diǎn)
埋點(diǎn)jedis 類Get、Set等API方法 簡(jiǎn)單直接 工作量大,方法較多、需要了解每個(gè)方法特性
埋點(diǎn) Connection sendCommand方法 全面、所有命令都會(huì)經(jīng)過此方法 存在未知風(fēng)險(xiǎn)、不方便計(jì)算執(zhí)行時(shí)間、和返回結(jié)果
埋點(diǎn) Protocol 全面、所有命令都會(huì)經(jīng)過此方法 存在未知風(fēng)險(xiǎn)、不方便計(jì)算執(zhí)行時(shí)間、和返回結(jié)果

PS:源碼中可以查看DevelopBootMain類,我看這代碼也看了2天,原來老寫業(yè)務(wù)代碼,看看這確實(shí)很容易懵X,確實(shí)這才是有技術(shù)含量的代碼。其實(shí)有沒有技術(shù)含量不太重要,重要是的有沒有商業(yè)價(jià)值。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述 最近稍微研究了一點(diǎn)Dubbo的RPC原理,在這里記錄一下筆記。 主要是閱讀源碼:https://github...
    木易光_閱讀 1,563評(píng)論 0 1
  • 說明:本文以以下配置進(jìn)行服務(wù)發(fā)布流程分析:注冊(cè)中心:zookeeper;發(fā)布協(xié)議:dobbo 1、服務(wù)發(fā)布流程解析...
    橋頭放牛娃閱讀 2,081評(píng)論 1 15
  • 1、RPC調(diào)用 dubbo服務(wù)調(diào)用只需在spring.xml中如下配置后,就可以調(diào)用本地方法一樣,調(diào)用provid...
    阿飛的博客閱讀 1,264評(píng)論 1 6
  • Dubbo 自 2011 年 10 月 27 日開源后,已被許多非阿里系的公司使用,其中既有當(dāng)當(dāng)網(wǎng)、網(wǎng)易考拉等互聯(lián)...
    程序員日常填坑閱讀 735評(píng)論 0 1
  • 清晨的陽光透著微風(fēng)徐徐吹來,春日里柔弱的陽光照著,今天是開學(xué)的第一天,依然起的早,已經(jīng)大二下了,回想自己在中文系的...
    曦日A閱讀 207評(píng)論 0 0

友情鏈接更多精彩內(nèi)容