[PHP 開源推薦] RDebug —— 滴滴開源的一款用於 RD 研發、自測、調試的實用工具

一、簡介
https://github.com/didi/rdebug

Rdebug 是滴滴開源的一款用於 RD 研發、自測、調試的實用工具,可以被用來提升 RD 研發效率、保障代碼質量進而減少線上事故。

1.1 背景
鑑於微服務具有易於擴展、部署簡單、技術異構性等優點,越來越多的服務都在採用微服務的架構模式。一個複雜的單體服務通常會被拆分成多個小的微服務,當然在享受微服務帶來的一系列便利的同時也要接受因爲微服務改造帶來的問題:需要維護的服務數變多、服務之間 RPC 調用次數增加……

在服務化改造完成之後,原來的單體服務演化成一堆微服務,這就造成線下開發測試環境維護成本大大增加,其次線下環境涉及到的部門較多,維護一個長期穩定的線下環境也是一個挑戰;業務快速發展、需求不斷迭代,手寫單測又因複雜的業務邏輯以及複雜的服務調用需要 mock 多個下游服務,導致手寫單測成本特別的高;手動構造數據,又不夠全面真實。以上問題都嚴重影響 RD 的研發效率,並且增加線上發生事故的隱患。

我們固執地相信這個行業需要一場變革。

1.2 宗旨
提升研發效率、降低測試成本、縮短產品研發週期,保障代碼質量、減少線上事故。

1.3 適用場景
適用於對已有接口進行代碼重構、功能升級,且該接口已經有錄製的流量。

不適合新開發的接口 或 未進行流量錄製的接口。

支持新接口的方案在調研中。

二、快速使用
錄製流量
# 修改 php-fpm 配置,打開 `clear_env = no` 選項

# 編譯 koala-libc.so 和 koala-recorder.so

# 啓動 php-fpm 注入 koala-libc.so 和 koala-recorder.so
# 先設置環境變量
$ export KOALA_SO=/path/to/koala-recorder.so
$ export KOALA_RECORD_TO_DIR=/path/to/your-save-recorded-session-dir
$ export LC_CTYPE="C"

# 啓動 php-fpm 開始錄製
# macOS
$ DYLD_INSERT_LIBRARIES="/path/to/koala-libc.so" DYLD_FORCE_FLAT_NAMESPACE="y" /path/to/sbin/php-fpm

# or, Linux
$ LD_PRELOAD="/path/to/koala-libc.so" /path/to/sbin/php-fpm
回放流量
回放支持 3 種方式:下載源碼回放、midi.phar 包回放、composer bin 回放。

# 直接用源碼回放
$ git clone https://github.com/didi/rdebug.git
$ cd rdebug/php/midi
$ sh install.sh
$ cd /path/to/your/project
$ /path/to/rdebug/php/midi/bin/midi run -f RECORD-SESSION-FILE

# 或,使用 phar 包回放
$ wget -O midi.phar -q https://github.com/didi/rdebug/raw/master/output/bin/midi.phar
$ midi.phar run -f RECORD-SESSION-FILE

# 或,Composer 全局安裝 midi(相比安裝到項目中,推薦全局安裝)
$ composer global require rdebug/midi
$ cd /path/to/your/project
$ ~/.composer/vendor/bin/midi run -f RECORD-SESSION-FILE

# 或,Composer 安裝到項目目錄下
$ cd /path/to/your/project
$ composer require rdebug/midi --dev
$ ./vendor/bin/midi run -f RECORD-SESSION-FILE
PHP 示例
使用 Docker 體驗錄製和回放
PHP 錄製和回放
PHP 回放本地文件
PHP 錄製方案
三、技術方案
因爲我們需要使用線上的真實流量來進行線下的回放測試,所以我們需要將線上的真實流量保存下來,然後將保存的真實流量在線下環境進行回放一遍。故 Rdebug 的核心技術方案就是 流量錄製和流量回放。

流量錄製: 即錄製線上服務的真實請求,包括調用下游服務的 RPC 請求。流量錄製的難點在於如何將上下游請求以及每次 RPC 的請求 / 響應一一對應。

流量回放: 即用線上錄製的流量,對線下測試代碼進行回放,通過流量匹配 mock 掉下游 RPC 請求。因此,流量回放的難點在於請求的攔截和匹配。

整體架構圖:

 

3.1 Koala & Koala-libc
Koala 和 Koala-libc 是 Rdebug 的核心引擎代碼,是流量錄製和回放的底層實現庫。

流量回放是基於流量錄製的代碼實現,大部分流量錄製需要關心的問題流量回放都需要關心,如 RPC 調用鏈跟蹤、libc 攔截等。所以流量回放和錄製共用同一套代碼。

Koala
Koala 主體部分用 Go 編寫,libc 系統調用攔截用少量的 C++ 編寫,編譯生成 koala-recorder.so (錄製) 和 koala-replayer.so (回放) 兩個 so 文件。

工作模式上分爲錄製和回放,回放的同時也在錄製。

更多細節見 koala 。

Koala-libc
Koala-libc 使用 C 編寫,編譯生成 koala-libc.so 文件。

由於 Go 不支持 fork,爲避免因爲 PHP-FPM fork worker 引起的問題,先把 koala-libc.so 注入到 PHP-FPM 的父進程,在子進程 worker accept 的時候再把 koala-recorder.so 給加載進來。

這樣 Koala-libc.so 會把 libc 系統調用攔截並轉發給 koala-recorder.so。

更多細節見 koala-libc 。

3.2 Midi
Midi 是 PHP 語言的流量回放客戶端,以命令行形式回放流量。

內嵌 koala-replayer.so 文件,以命令行的方式、使用線上錄製的流量,對線下代碼進行回放,解析並對比回放結果,生成對比報告、Trace 報告、覆蓋率報告等。

Midi 也支持 Xdebug 聯動,對被測代碼設置斷點,進行單步調試,方便於研究代碼和排查問題。

更多細節見 midi 。

四、編譯
4.1 要求
Koala & Koala-libc
GCC >= 4.8
Go >= 1.8
Glide
Midi
macOS/Linux
PHP >= 7.0
Xdebug (可選)
Composer(可選)
4.2 編譯 Koala-libc
$ cd koala-libc
$ sh build.sh
將編譯生成 ../output/libs/koala-libc.so。

4.3 編譯 Koala
$ cd koala

# install depends
$ sh build.sh vendor

# koala-recorder.so
$ sh build.sh recorder

# koala-replayer.so
$ sh build.sh
將編譯生成 ../output/libs/koala-recorder.so 和 ../output/libs/koala-replayer.so。

4.4 編譯 midi.phar
開始編譯 phar 包之前,建議在當前環境下編譯生成 koala-replayer.so,並存放到 php/midi/res/replayer/koala-replayer.so。

倉庫中默認攜帶的 so ,只適用 macOS。

$ cd php/midi
$ sh build.sh
編譯將會生成 ../output/bin/midi.phar。

默認情況下,編譯 phar 不包含 DiPlugin(php/midi/src/DiPlugin)插件。

DiPlugin 是滴滴內部的一個插件。如果需要包含 DiPlugin 插件,使用如下命令:

$ cd php/midi
$ sh build.sh midi-diplugin
五、使用
5.1 流量錄製
流量錄製 是在線上生產環境中,把真實的線上流量錄製下來,存儲到本地文件 或者 存儲到 elastic 中。

通過 KOALA_RECORD_TO_DIR 環境變量,將錄製的流量存儲到指定的目錄下。

macOS 和 Linux 下錄製注入 so 的命令不同,分別是 DYLD_INSERT_LIBRARIES 和 LD_PRELOAD,其他環境變量和命令一致。

滴滴已在生產環境錄製。更多 錄製介紹。

5.1.1 macOS 錄製
$ DYLD_INSERT_LIBRARIES="/path/to/koala-libc.so:/usr/lib/libcurl.dylib" DYLD_FORCE_FLAT_NAMESPACE="y" LC_CTYPE="C" KOALA_SO=/path/to/koala-recorder.so KOALA_RECORD_TO_DIR=/tmp /usr/local/sbin/php-fpm
5.1.2 Linux 錄製
LD_PRELOAD="/path/to/koala-libc.so /usr/lib64/libcurl.so.4" LC_CTYPE="C" KOALA_SO="/path/to/koala-recorder.so" KOALA_RECORD_TO_DIR=/tmp /usr/local/sbin/php-fpm
Koala 也提供一種將流量寫入到 elastic 的方式(僅供參考),只需要將環境變量 KOALA_RECORD_TO_DIR 替換成 KOALA_RECORD_TO_ES,值爲 elastic 寫入的 Url。

5.2 流量回放
流量回放 是使用線上錄製好的流量,在本地環境(macOS 或者 linux)下回放,只需要部署當前模塊的代碼,不需要搭建下游依賴等環境。

下面介紹最簡單的 -f 回放,指定錄製的文件進行回放:

5.2.1 回放
# Source
$ /path/to/rdebug/php/midi/bin/midi run -f RECORD-SESSION-FILE

# Or, phar
$ midi.phar run -f RECORD-SESSION-FILE

# Or, composer vendor bin
$ ./vendor/bin/midi -f RECORD-SESSION-FILE
更多細節見 流量回放

如果回放失敗,加上參數 -v、-vv 或 -vvv 查看詳細日誌。

5.2.2 報告
參數 -R,-T,-C 等選項,支持生成報告:回放報告、Trace 報告、代碼覆蓋率報告等。

報告示例:

 

 

 

更多細節見 Midi。

擯棄世俗浮躁,追求技術精湛

————————————————
原文作者:Summer
轉自鏈接:https://learnku.com/php/t/41361

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章