『互聯(lián)網架構』dubbo 調用埋點(114)

原創(chuàng)文章,歡迎轉載。轉載請注明:轉載自IT人故事會,謝謝!
原文鏈接地址:『互聯(lián)網架構』dubbo 調用埋點(114)

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

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

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

節(jié)點 角色說明
Provider 暴露服務的服務提供方
Consumer 調用遠程服務的服務消費方
Registry 服務注冊與發(fā)現的注冊中心
Monitor 統(tǒng)計服務的調用次數和調用時間的監(jiān)控中心
Container 服務運行容器
  • Dubbo調用過程


  • 消費者調用過程


(二)調用端埋點實現

  • 埋點目的
    1.捕捉消費者調用信息(遠程接口、URL、參數、用時、返回結果、異常)
    2.傳遞TraceRequest

  • 調用信息模型表結構

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

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

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


  1. 選擇斷點位置Debug調試調用過程
  2. 消費者調用線程源碼分析:


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

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

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

(三)調用端埋點實現

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


經分析埋點位置選在離實際調用方法較遠的EchoFilter過濾器理由是捕捉的信息更全面。

具體會話開啟過程:

  1. 基于Attachment獲取TraceId、ParentId、TraceProperties。
  2. 封裝TraceRequest ,并此為參數開啟會話。
  3. 在調用結束時關閉會話。
    具體源碼參見:com.cbt.agent.collects.dubbo.DubboProviderMonitorHandle#invokerBefore

(二)Servlet處理埋點

  • Servlet埋點目的
    1.生成TraceId
    2.開啟關閉監(jiān)控會話
    3.捕捉Http請求(url、客戶端IP、參數、響應時長、響應狀態(tài)碼)

  • 埋點埋在哪?
    1.每一個Control方法
    2.DispatcherServlet.doDispatch方法
    3.HttpServlet.service 方法

  • 方案對比

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

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

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

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

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

請求攔截是指具體Http請求過來時進行攔截過濾,這么做主要是為了完成兩個目的

1.開啟監(jiān)控會話
2.開啟對Servlet響應過程的監(jiān)控

(三)Redis 調用埋點

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

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

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

相關閱讀更多精彩內容

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

友情鏈接更多精彩內容