基於 eBPF 技術的開源項目 Kindling 之 HTTP 協議解析
Kindling 是一款基於 eBPF 技術的雲原生可觀測性開源項目。本文將主要介紹如何通過 Kindling 對 HTTP 協議進行解析。
在故障排查過程中,我們通常對請求性能、請求內容和返回內容感興趣。這使我們能知道請求和接收了什麼內容,是否有異常等基本信息。如何獲取請求的具體詳細信息,傳統方式是通過 tcpdump 獲取請求包數據,然後通過 wireshark 查看其具體協議內容。
tcpdump 雖然在生產環境中經常使用,但由於獲取的數據量和大小限制,不適合一直開啓,只有在排查問題時使用。而獲取的數據也無法直接查看,需下載到本地通過 wireshark 分析查看。基於 tcp 的諸多問題,所以 Kindling 通過 eBPF 方式實現請求的具體分析。
那麼 Kindling 是如何實現實時可用的協議解析功能呢?主要涉及 3 塊功能:
-
數據採集
-
請求 / 響應關聯
-
請求 / 響應解析
數據採集
先來查看下一個簡單的 HTTP 服務
HTTP 服務僞代碼
當接收到請求時會有 accept/read/write/close 等函數執行,這些函數最終執行內核的系統調用。
HTTP 服務接收請求流程圖
使用 strace 命令查看一次請求的系統調用情況
-
read 接收 HTTP 請求 / test
-
第一個 write 日誌輸出
-
第二個 write 返回 HTTP 結果
從日誌中可分析出,請求通過 read 系統調用,日誌和響應都是通過 write 系統調用。
Kindling 已實現對系統事件調用進行抓取,並將相關的 read 和 write 系統調用轉換爲 Kindling 事件,最終生成 3 條事件。事件格式定義可參見 kindling_event.proto。
系統調用與 Kindling 事件映射
參數說明:
-
fd 讀寫請求的文件描述符
-
size 請求報文大小
-
res 返回大小
-
data 請求報文內容
-
latency 讀 / 寫操作耗時
-
category 事件類型,NET 是指網絡事件,FILE 是文件讀寫事件
請求 / 響應關聯
常規的 TCP 請求都會用同一個 FD 進行通信,只需根據進程號和 FD 就能關聯同一個請求和響應。
請求 / 響應解析
雖然有了報文,但不同的協議定義的規範也不同。那麼如何知道該報文是什麼協議,並且用該協議進行解析呢?主要涉及 2 塊內容:
-
協議識別
-
協議解析
協議識別
通過特徵或關鍵字快速匹配協議,減少協議解析的次數,提升整體解析的性能。
HTTP 報文規範
對於 HTTP 請求來說,通過 HTTP 版本號 (HTTP/1.0 或 HTTP/1.1) 可以快速識別協議。
但由於抓包大小限制,如果一個請求的 URL 長度超過包的大小,那麼無法獲取後續的 HTTP 版本號,於是採用端口協議配置方式也能識別協議。
協議解析
協議解析是爲了產生指標用於後續分析,在解析過程中需根據協議自身的格式進行解析。
由於報文內容是 byte 數組格式,Kindling 提供了封裝好的 API 用於解析。
以 HTTP 協議爲例,可解析出如下信息:
-
請求行 - 方法、URL 信息
-
HTTP 頭信息 - traceId 信息
-
狀態行 - 狀態碼信息
解析 HTTP 請求
解析請求過程就是對請求進行逐幀解析,讀取到對應的屬性後最終將值存儲到 attribute 中
解析HTTP響應
解析響應跟解析請求類似,也是逐幀解析,將解析出的屬性存儲到 attribute 中。
此外,需考慮報文非法場景(狀態碼非數值),確保解析正常結束。
歡迎對雲可觀測性感興趣的小夥伴加入 Kindling 大家庭
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/icpdb3G90tb3C_lH2ohwUw