PDF書籍《手寫調用鏈監控APM系統-Java版》第9章 插件與鏈路的結合:Mysql插件實現

本人閱讀了?Skywalking?的大部分核心代碼,也了解了相關的文獻,對此深有感悟,特此借助巨人的思想自己手動用JAVA語言實現了一個?“調用鏈監控APM”?系統。本書采用邊講解實現原理邊編寫代碼的方式,看本書時一定要跟著敲代碼。

作者已經將過程寫成一部書籍,奈何沒有錢發表,如果您知道渠道可以聯系本人。一定重謝。

本書涉及到的核心技術與思想

JavaAgent , ByteBuddy,SPI服務,類加載器的命名空間,增強JDK類,kafka,插件思想,切面,鏈路棧等等。實際上遠不止這么多,差不多貫通了整個java體系。

適用人群

自己公司要實現自己的調用鏈的;寫架構的;深入java編程的;閱讀Skywalking源碼的;

版權

本書是作者嘔心瀝血親自編寫的代碼,不經同意切勿拿出去商用,否則會追究其責任。

原版PDF+源碼請見:

本章涉及到的工具類也在這里面:

PDF書籍《手寫調用鏈監控APM系統-Java版》第1章 開篇介紹-CSDN博客

第9章 插件與鏈路的結合:Mysql插件實現

9.1 Mysql插件的流程分析

數據庫歸根結底就是JDBC的操作,在學習時期,我們肯定會學習基本的jdbc查詢數據庫的寫法:

// 1. 加載驅動
Class.forName("com.mysql.jdbc.Driver");
// 2. 獲取連接 對象
ConnectionImpl connection = (ConnectionImpl) DriverManager.getConnection("", "", "");
// 3. 準備 statement
PreparedStatement statement = connection.prepareStatement("select * from t_user");
// 4. 執行sql
statement.executeQuery();

無論用什么框架,數據庫操作都避免不了上面原始步驟。我們分析下上面的流程:

1. 加載驅動,我們不關心。

2. 通過DriverManager的靜態方法getConnection獲取到ConnectionImpl 連接對象。

3. 通ConnectionImpl的prepareStatement方法,去配合sql準備一個PreparedStatement 。

4. 最后通過PreparedStatement的executeQuery方法去查詢sql語句并返回結果。

數據庫插件要想采集到調用的sql信息,就必須要攔截ConnectionImpl類的prepareStatement方法。 如果還要采集sql調用的返回信息,還需要攔截 PreparedStatement 類的executeQuery方法。但是我們還需要數據庫服務器的地址信息,這個還必須要攔截 DriverManager.getConnection 。

攔截的三個類我們梳理出來了,但是這里有個很嚴重的問題,當我們攔截DriverManager.getConnection獲取到數據庫地址后,沒辦法向后傳遞到ConnectionImpl類的prepareStatement中。

我們架設一個猜想:

攔截DriverManager.getConnection返回的是ConnectionImpl。如果能在這個階段將數據庫的地址信息設置到返回的ConnectionImpl對象中,后面攔截ConnectionImpl的prepareStatement方法時,方法切面那里是不是有個參數能獲取到當前對象,也就能拿到DriverManager.getConnection攔截時的數據庫信息了。

這也就需要在增強類中添加Object字段,用于參數傳遞的思想。

我們目前的字節碼增強代碼時無法實現上述思想的,需要進行改造。接下來我們來講解下如何實現。

9.2 插樁類改造,新增Object字段和實現EnhancedInstance接口

由于篇幅過長,請到第一章查看原版PDF和源碼:

PDF書籍《手寫調用鏈監控APM系統-Java版》第1章 開篇介紹-CSDN博客


9.3 Mysql插件真正實現

根據前面的分析,我們依次需要攔截

類名: java.sql.DriverManager

方法:getConnection

JDK類庫

然后攔截:

類名: com.mysql.jdbc.ConnectionImpl

方法:prepareStatement

非JDK類庫

最后攔截:

類名: com.mysql.jdbc.PreparedStatement

方法:executeQuery

非JDK類庫

在插件模塊下新增apm-mysql-plugin項目,POM內容:

<dependency><groupId>com.hadluo.apm</groupId><artifactId>apm-commons</artifactId><version>1.0</version>
</dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.44</version><scope>provided</scope>
</dependency>

hadluo-apm-plugin.def 插件定義文件:

mysql5-DriverConnect=com.hadluo.apm.plugin.mysql5.DriverConnectInstrumentationmysql5-PrepareStatement=com.hadluo.apm.plugin.mysql5.PrepareStatementInstrumentationmysql5-PrepareStatementExecute=com.hadluo.apm.plugin.mysql5.PrepareStatementExecuteInstrumentation

三個類我就不建了,值得注意的是,DriverManager#getConnection方法最終調用下面方法:

DriverConnectInstrumentation配置攔截類名時,還需要指定參數簽名:

還有就是isBootstrapInstrumentation 一定要返回true, 因為它是rt.jar的JDK類。

三個方法環繞執行器分別是:

DriverConnectInterceptor

PrepareStatementInterceptor

PrepareStatementExecuteInterceptor

DriverConnectInterceptor 代碼實現:

由于篇幅過長,請到第一章查看原版PDF和源碼:

PDF書籍《手寫調用鏈監控APM系統-Java版》第1章 開篇介紹-CSDN博客

打包測試,kafka數據json如下:

{"msgTypeClass": "com.hadluo.apm.commons.kafka.Segment","sampleTime": 1734056030540,"serviceName": null,"serviceInstance": "1a91d6d937ea4d6b8c2cb34dc75bf240@192.168.2.125","traceId": "c133c183325b48fdbd3c94eca8bf341e.44.17340560303730001","traceSegmentId": "c133c183325b48fdbd3c94eca8bf341e.44.17340560303710000","spans": [{"spanId": 1,"parentSpanId": 0,"startTime": 1734056030528,"endTime": 1734056030529,"refs": [],"operationName": "jdbc:mysql://127.0.0.1:3306/test/select * from t_user/executeQuery","peer": null,"spanType": "Exit","spanLayer": "DB","component": "MySQL","tags": {"remotePeer": "jdbc:mysql://127.0.0.1:3306/test","extra": "{password=, user=root}","sql": "select * from t_user"},"logs": {}},{"spanId": 0,"parentSpanId": -1,"startTime": 1734056030373,"endTime": 1734056030538,"refs": [],"operationName": "/order","peer": null,"spanType": "Entry","spanLayer": "HTTP","component": "Tomcat","tags": {"http.method": "GET","url": "/order"},"logs": {}}]
}

上述json我想應該很熟悉了,不用我過多分析,只是還有一個問題,就是serviceName為空。 熟悉SkyWalking的讀者都應該知道,應用名稱是在啟動參數上通過 agent name 來配置的。

作者不這樣做,我們可以攔截SpringBoot的啟動流程,在解析到Enviroment后,將 spring.application.name 的值設置到Config,

當然,這僅限制于springboot服務生效。下節我們就來分析如何攔截springboot的Enviroment。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/64162.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/64162.shtml
英文地址,請注明出處:http://en.pswp.cn/web/64162.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于Vue的子組件改變父組件傳來的值

一、組件直接傳值 大家都知道父子組件傳值的方案&#xff0c;有以下幾個&#xff0c;不再詳細敖述 Props&#xff1a;父組件向子組件傳遞數據 $emit&#xff1a;子組件通過自定義事件向父組件傳遞數據 .sync修飾符&#xff1a;一個方便且強大的工具&#xff0c;可以簡化父子組…

Flink的Watermark水位線詳解

一、Flink的時間語義 Flink有如下三種時間語義&#xff1a; Flink的三種時間語義-CSDN博客 在實際應用中&#xff0c;一般會采用事件時間語義。而正如前面所說的&#xff0c;事件時間語義需要等窗口的數據全部到齊了&#xff0c;才能進行窗口計算。那么&#xff0c;什么時候數…

ES學習Promise對象(九)

這里寫目錄標題 一、概念二、示例基本使用使用 Promise 對象封裝Ajaxthen() 方法catch() 方法 一、概念 簡單說就是一個容器&#xff0c;里面保存著某個未來才會結束的事件&#xff08;通常是一個異步操作&#xff09;的結果。Promise 是一個對象&#xff0c;Promise 提供統一…

Kibana:LINUX_X86_64 和 DEB_X86_64兩種可選下載方式的區別

最近需要在vm&#xff08;操作系統是 Ubuntu 22.04.4 LTS&#xff0c;代號 Jammy。這是一個基于 x86_64 架構的 Linux 發行版&#xff09;上安裝一個7.17.8版本的Kibana&#xff0c;并且不采用docker方式。 在下載的時候發現有以下兩個選項&#xff0c;分別是 LINUX_X86_64 和 …

CMake 構建項目并整理頭文件和庫文件

本文將介紹如何使用 CMake 構建項目、編譯生成庫文件&#xff0c;并將頭文件和庫文件整理到統一的目錄中以便在其他項目中使用。 1. 項目結構 假設我們正在構建一個名為 rttr 的開源庫&#xff0c;初始的項目結構如下&#xff1a; D:\WorkCode\Demo\rttr-master\|- src\ …

【FAQ】HarmonyOS SDK 閉源開放能力 — Vision Kit(2)

1.問題描述&#xff1a; 人臉活體檢測返回上一頁App由沉浸式變為非沉浸式多了上下安全區域。 解決方案&#xff1a; 檢測結束后需要自己去設置沉浸式配置。 2.問題描述&#xff1a; Vision Kit文字識別是本地識別&#xff0c;還是上傳至服務器&#xff0c;由服務器來識別文…

AIA - IMSIC之二(附IMSIC處理流程圖)

本文屬于《 RISC-V指令集基礎系列教程》之一,歡迎查看其它文章。 1 ???????通過IMSIC接收外部中斷的CSR 軟件通過《AIA - 新增的CSR》描述的CSR來訪問IMSIC。 machine level 的 CSR 與 IMSIC 的 machine level interrupt file 可相互互動;而 supervisor level 的 CSR…

Vue單頁應用的配置

前面通過幾篇文章了解并掌握了 Vue 項目構建及運行的前期工作 。接下來我們可以走進 Vue 項目的內部&#xff0c;一探其內部配置的基本構成。 1. 路由配置 由于 Vue 這類型的框架都是以一個或多個單頁構成&#xff0c;在單頁內部跳轉并不會重新渲染 HTML 文件&#xff0c;其路…

CocosCreator-引擎案例-TS:spine

工程1&#xff1a;LoadSpine&#xff1a;簡單加載spine資源 建立工程&#xff0c;在層級上建立一個空對象&#xff0c;改名spine 在spine上添加spine組件&#xff1a; 添加組件>渲染組件>spine 在spine上掛上腳本loadspine onLoad () {cc.resources.load(loadSpine/ali…

使用FreeNAS軟件部署ISCSI的SAN架構存儲(IP-SAN)練習題

一&#xff0c;實驗用到工具分別為&#xff1a; VMware虛擬機&#xff0c;安裝教程&#xff1a;VMware Workstation Pro 17 安裝圖文教程 FreeNAS系統&#xff0c;安裝教程&#xff1a;FreeNAS-11.2-U4.1安裝教程2024&#xff08;圖文教程&#xff09; 二&#xff0c;新建虛…

【ANGULAR網站開發】初始環境搭建

1. 初始化angular項目 1.1 創建angular項目 需要安裝npm和nodejs&#xff0c;這邊不在重新安裝 直接安裝最新版本的angular npm install -g angular/cli安裝指定大版本的angular npm install -g angular/cli181.2 啟動angular 使用idea啟動 控制臺啟動 ng serve啟動成功…

lua debug相關方法詳解

lua debug相關方法詳解 1. debug.debug()2. debug.getinfo(func | level [, what])3. debug.getlocal(func-or-level, localindex)4. debug.setlocal(level, local_number, value)5. debug.getupvalue(func, upvalue_index)6. debug.setupvalue(func, upvalue_index, value)7. …

《計算機網絡(第7版)-謝希仁》期末考試復習題和答案(總結整理)

目錄 前言&#xff1a; 一、選擇題。 二、填空題。 三、名詞解釋。 四、簡答題。 前言&#xff1a; 這個自動標題自己帶了序號&#xff0c;一開始想全部選項和題號都改過來的&#xff0c;結果一看一百多個全是&#xff0c;懶得改了 一、選擇題。 1、廣域網覆蓋的地理范圍…

【再談設計模式】享元模式~對象共享的優化妙手

一、引言 在軟件開發過程中&#xff0c;我們常常面臨著創建大量細粒度對象的情況&#xff0c;這可能會導致內存占用過高、性能下降等問題。享元模式&#xff08;Flyweight Pattern&#xff09;就像是一位空間管理大師&#xff0c;它能夠在不影響功能的前提下&#xff0c;有效地…

Milvus×EasyAi:如何用java從零搭建人臉識別應用

如何從零搭建一個人臉識別應用&#xff1f;不妨試試原生Java人工智能算法&#xff1a;EasyAi Milvus 的組合拳。 本文將使用到的軟件和工具包括&#xff1a; EasyAi&#xff1a;人臉特征向量提取Milvus&#xff1a;向量數據庫用于高效存儲和檢索數據。 01. EasyAi&#xff1a;…

NS3學習——tcpVegas算法代碼詳解(2)

NS3學習——tcpVegas算法代碼詳解&#xff08;1&#xff09;-CSDN博客 目錄 4.TcpVegas類中成員函數 (5) CongestionStateSet函數 (6) IncreaseWindow函數 1.檢查是否啟用 Vgas 2.判斷是否完成了一個“Vegas 周期” 2.1--if&#xff1a;判斷RTT樣本數量是否足夠 2.2--e…

GitLab 將停止為中國區用戶提供服務,60天遷移期如何應對? | LeetTalk Daily

“LeetTalk Daily”&#xff0c;每日科技前沿&#xff0c;由LeetTools AI精心篩選&#xff0c;為您帶來最新鮮、最具洞察力的科技新聞。 GitLab作為一個廣受歡迎的開源代碼托管平臺&#xff0c;近期宣布將停止服務中國大陸、澳門和香港地區的用戶提供服務。根據官方通知&#x…

華為實訓課筆記 2024 1223-1224

華為實訓 12/2312/24 12/23 [Huawei]stp enable --開啟STP display stp brief --查詢STP MSTID Port Role STP State Protection 實例ID 端口 端口角色 端口狀態 是否開啟保護[Huawei]display stp vlan xxxx --查詢制定vlan的生成樹計算結…

企業數字化轉型中如何區分“IT投入”和“業務投入”

在數字化轉型的浪潮中&#xff0c;企業往往面臨一個關鍵問題&#xff1a;如何區分“IT投入”和“業務投入”&#xff1f;在很多企業中&#xff0c;這兩個概念往往被混淆&#xff0c;不少公司甚至認為“數字化轉型”就是“IT的事情”&#xff0c;但實際上&#xff0c;它們之間有…

【Spring AI】Spring AI Alibaba的簡單使用

提示&#xff1a;文章最后有詳細的參考文檔。 前提條件 SpringBoot版本為3.x以上JDK為17以上申請api-key&#xff0c;地址&#xff1a;百煉平臺 引入依賴 說明&#xff1a;我的springboot版本為3.2.4&#xff0c;spring-ai-alibaba-starter版本為1.0.0-M2.1(對應spring-ai版本…