基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術

OpenAnolis小助手發表於2022-10-13

文/ eBPF 技術探索 SIG

隨著 eBPF 技術的廣泛應用,在作業系統層面提供了更多的觀測能力,站在作業系統層面對應用的行為資料進行 trace 追蹤成了一種應用監控的新手段,本文主要介紹基於 eBPF 實現對應用網路資料監控的背後邏輯。

一、一個請求資料包的組成

一個完整的應用請求資料包主要包含請求地址資訊及具體的請求資料。其中請求地址資訊就是我們常說的五元組資訊(IP+埠+協議),這部分都是作業系統協議棧負責去解析;而請求資料則由應用透過各種協議去封裝並解析,常見的應用協議有:http、mysql、rediis、dns 等。

基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術

應用每一個請求資料的接受與傳送都是透過網路相關的系統呼叫與作業系統互動,如果請求報文沒有加密,那麼在系統呼叫處做一個攔截透過函式入參就能輕而易舉的拿到應用協議資料。當下熱門的應用可觀測都是基於此方法對應用網路資料進行trace,包括:時延、流量統計、協議等。

二、基於系統呼叫的請求追蹤

2.1 網路請求模型

一個應用程式基於系統呼叫的網路請求模型如下(這裡僅介紹客戶端):

  • 透過 socket 去建立套接字,獲得一個 fd 作為 socket 的標識。

  • 透過 connect 填寫 IP 埠資訊發起請求連線。

  • 透過read/write請求/接收具體資料,除了read/write系統呼叫還有send/recvfrom,readv/writev 等可用。

  • 透過 close 結束本次請求。

基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術

透過上面的流程圖我們大概瞭解了一次完整網路請求的系統呼叫邏輯。有幾點需要注意:

  • 對於單個建鏈完成的請求而言,其傳送資料和接收資料往往是序列的,或者說一個 write 必然匹配一個 read,因此我們才能統計到 RT 時間,而 read/write 的返回位元組數就可以作為我們的流量統計。

  • write/read 如何配對,對於客戶端而言,是先 write 再 read,常用的做法是透過程式 pid 和 socket fd 作為配對標識,實現 write/read 這一次完整請求資料的配對。

2.2 系統呼叫追蹤

eBPF 技術可以在不改變核心原始碼或載入核心模組情況下在核心插入指定 hook 程式碼,能在核心或應用程式執行到一個特定的 hook 點時執行。預定義的 hooks 包含系統呼叫、 函式出/入口、核心追蹤點、網路事件等等。

基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術

有了 eBPF 做系統呼叫的 hook 以後,系統呼叫的事件採集對於我們來說變得格外方便,只不過我們需要注意下哪些事件需要上報及請求資料上報以後的匹配策略。同時對於獲取請求資料是有一些講究,對於 write 傳送資料而言在系統呼叫函式入口直接獲取入參就可以獲取資料,但是對於 read 讀取資料而言我們需要在系統呼叫函式的出口做 hook 去拿資料。

上文中提到 pid+fd 作為 traceid 作為請求的唯一標誌,有如下兩種方法可以實現:

方法1:當有 connect 的時候先在 BPF map 中記錄下這個 traceid,表示有一個新的請求建立,後續的 read/write 請求資料都是以此為配對。不過在 http 長連線場景下,connect 發起可能在我們 trace 之前,所以只能透過 netlink 等其他方式來獲取連結資訊。

基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術

方法2:實際上我們關心的只是 read/write 的請求資料及如何配對,是否可以僅根據 fd 獲取連線資訊?BPF 程式可以拿到當前程式的 task_struct,根據 fd 可以拿到對應的 sock 結構體,sock 結構體中記錄了請求地址資訊。

基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術

除此之外就是 BPF 框架的技術選型,我們採用了 Coolbpf 開發,透過對 libbpf 的改進,在具備 core 特性的同時提供了更簡潔的 API 介面,exporter 程式可以直接以 so 的形式載入程式碼。以上只是網路請求事件採集的最小單元,藉助 exporter 的其他能力,可以獲得更豐富的資料指標:錯誤數、時延、程式級流量統計等。

三、應用協議識別

在系統呼叫層面只能識別到 4 層網路協議,對於應用的 7 層協議無法識別,實際上是在 hook 系統呼叫拿到 buf 引數後,對 buf 的頭部幾個位元組做協議頭解析,目前支援的協議有:http、mysql、kafak、dns、mongo、pgsql、dubbo。對於 https 等加密報文可以透過 uprobe 的方式對 ssl 加密庫做 hook,後續會支援這部分功能。

四、部署

我們在日常值班問題中也有碰到各種網路抖動時延問題,因此我們將此部分功能放在了 SysOM 智慧診斷平臺的 agent 中,可以透過容器一鍵部署,並在 grafana 中檢視對應的時延分佈及具體的時延請求資訊。

基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術

同時我們與 sls 合作,也將此部分核心採集的能力輸出給了 iLogtail。

五、what's more

除了上文提到的基於系統呼叫的應用觀測,對於應用由於自身原因收包緩慢造成網路“假抖動”的情況,我們基於 Coolbpf 也做了相關觀測實踐。一個完整的收包流程主要分為兩個階段:

階段1:OS 透過軟中斷將資料包上送到應用的收包佇列並通知程式後就算完成了協議棧的收包工作。

階段2:應用得到通知後去收報佇列取包。

基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術

這兩個階段可以認為是非同步的,我們將資料包到達收包佇列到應用完成取包這段時間作為應用的"收包延遲時間"進行觀測,基於此方法在網路抖動問題定位中得到了極大幫助。

案例1 某業務應用基於 dubbo 框架容器收到 tcp 包後延遲了將近 1s 業務層才收到

部署 SysOM agent 對“收包延遲時間”進行觀測,發現"收包延遲時間"將近 1 秒,右側紅框部分為時間,單位為納秒,結合左側紅框每次發生延遲時間都在某某時間 42 秒,懷疑跟業務某定時任務相關造成應用自身時延,最終排查到業務有某個任務會定時收集 jvm 的引數,對應用有 stop 動作,停掉該任務後消除了抖動問題。

基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術

案例2 業務高峰期,客戶端 rpc 耗時比服務端多 20-30ms

業務監控如下:

基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術

部署 SysOM agent 對“收包延遲時間”進行觀測,發現對應時間段存在應用“收包延遲時間”較大,因此首先排除了網路鏈路問題。紅框部分為時間,單位為納秒,圖中時間需要加上 8 小時。

基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術

根據時序對比發現是由於此時間段應用在做 GC 導致,最後透過調整 GC 引數解決。

基於 Coolbpf 的應用可觀測實踐 | 龍蜥技術

六、總結

以上是基於 Coolbpf 在可觀測性的相關實踐,相關功能都整合在了 SysOM 的 agent 中,後續會引入更多對應用觀測的功能。當應用日誌無法解決問題或者沒有日誌的情況下,利用 eBPF 技術在 OS 層面對應用行為邏輯的觀測,在定位某些應用的疑難問題時有著極大幫助。

參考連結可移步龍蜥公眾號(OpenAnolis龍蜥)2022年10月11日相同推送檢視。

—— 完 ——


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70004278/viewspace-2918210/,如需轉載,請註明出處,否則將追究法律責任。

相關文章