CNCF Observability Whitepaper 中除了 Metrics、Logs、Traces 之外,也列出了 Profiles 與 Dumps 兩種訊號。本章聚焦 Profiles 與 eBPF (Extended Berkeley Packet Filter),並介紹兩個對應的開源專案:Grafana Pyroscope 與 Grafana Beyla。
Profiles 與 Continuous Profiling#
Profiles 與 Dumps 的定位分工如下:
- Profiles:監測程式執行時對 CPU、Memory、Network 等硬體資源的使用狀況,協助找出效能瓶頸所在的程式片段。
- Dumps:在系統出錯當下保留記憶體快照、Stack Trace 等狀態,事後可回溯分析。
當服務跑在微服務架構上時,Metrics、Logs、Traces 已能定位到「哪個服務、哪個 Request 慢了」,但要再下鑽到「哪一行程式碼、哪個函式或物件」造成瓶頸,就需要 Profiles。執行 Profiles 量測的工具稱為 Profiler,各語言都有自己的選項:
- Python:cProfile 紀錄執行細節,搭配 SnakeViz 視覺化。
- Java:可參考 Baeldung 的 A Guide to Java Profilers,列舉了多種商業與開源 Profiler。
傳統上 Profiler 多用於開發階段、以測試資料驗證問題;上生產環境的最大顧慮是持續取樣會吃掉一定比例的 CPU 與記憶體。隨著取樣技術與 Kernel 端機制的演進,這個成本越來越能接受,於是「在生產環境長時間開著的 Profiling」逐漸成為一種實踐,也就是 Continuous Profiling(持續性 Profiling)。
Grafana Pyroscope#
2023 年 3 月 Grafana Labs 收購了 Pyroscope。它能持續觀測 CPU 與 Memory 使用情況,並以火焰圖(Flame Graph)視覺化,讓使用者快速看出哪段呼叫鏈佔用最多資源。Pyroscope 提供兩條資料收集路徑:
- SDK:把資料採集相關程式碼直接嵌入應用程式中,可以做更細緻的客製化,但需要動程式碼。
- eBPF:利用 eBPF 在 Linux Kernel 層收集資料,不必改動應用程式碼,但需要相對新版的 Linux Kernel。
兩條路徑各有權衡:SDK 路徑會與語言執行階段綁得更深、可以追到語言層級的細節(例如 goroutine、Heap 物件分配);eBPF 路徑則是低侵入但精度較粗。Pyroscope 在 Go 語言上的支援最完整,CPU、Memory、goroutine 等資料都能取得;Java、Python 等語言目前主要能採集 CPU 資訊,其他維度仍在持續擴充中。
eBPF:在 Kernel 中安全地執行小程式#
eBPF 是 Linux Kernel 提供的一種機制,允許使用者撰寫小程式並掛載到 Kernel 內的特定 hook point。當預先約定的事件發生(例如網路封包到達、系統呼叫被執行),對應的 eBPF 程式會被觸發執行,於是可以在很底層的位置觀察、收集甚至改寫行為。由於整個過程執行在核心層,效率高且能取得原本應用層拿不到的資訊;同時 Kernel 會對 eBPF 程式做嚴格的驗證(包括程式不能無限迴圈、不能存取任意記憶體),以避免影響系統穩定。
eBPF 名稱中的 BPF(Berkeley Packet Filter)原本只用於網路封包過濾,eBPF 則大幅擴充其功能與應用範圍,現在已被視為一項獨立的技術。它於 2014 年首次推出,多年下來社群圍繞 eBPF 衍生出大量開源專案,並在 2021 年由 Meta、Google、Microsoft、Netflix 等公司共同成立 eBPF Foundation。
在 Observability 與安全領域,eBPF 已有不少實際應用:
- Cilium:以 eBPF 實作 Kubernetes 網路安全與流量控制。
- Falco:以 eBPF 進行容器層級的安全監控。
- Pixie:以 eBPF 實作 Kubernetes 應用層觀測,無需改動應用程式即可取得 HTTP、DB 等請求細節。
更多專案與案例可參考 eBPF.io 上的 Project Landscape 與 Case Studies。
Grafana Beyla:以 eBPF 實作的零侵入 Auto-Instrumentation#
Beyla 是 Grafana 開源的 eBPF 工具,定位是「零侵入式取得應用程式的 Metrics 與 Traces」。它監聽 Linux OS 上 HTTP、HTTPS、gRPC 流量,在不修改應用程式碼的前提下產生對應的觀測資料。
實務上會把 Beyla 收到的 Metrics 餵給 Prometheus,再用 Grafana 畫出 RED Metrics Dashboard。對於既有不易改動的服務、或是不想為了觀測而引入大量 SDK 依賴的場景,這是一條值得考慮的路徑。
Lab:Pyroscope 加上 eBPF#
範例專案以 Docker Compose 啟動下列服務:
- FastAPI App(fastapi):以 Pyroscope Python SDK 收集 Profile 並送到 Pyroscope。
- Spring Boot App(spring-boot):以 Agent Jar 形式掛上 Pyroscope Java SDK 收集 Profile。
- Grafana Agent:以 eBPF 方式收集所有 Container 的 Profile 並送到 Pyroscope。
- Pyroscope:接收 Profile 並提供 Web UI 查詢。
- Grafana:以 Pyroscope Data Source 查詢資料。
啟動與打流量:
docker-compose up -d
k6 run --vus 1 --duration 300s k6-script.jsPyroscope UI(http://localhost:4040)的左上下拉選單可切換來源:fastapi(Python SDK)、spring-boot(Java SDK)、compose-example(Grafana Agent eBPF)、pyroscope(Pyroscope 自己)。也可在 Grafana Explore 中選擇 Pyroscope Data Source,以 process_cpu - cpu 為條件,例如:
# 範例查詢條件
{service_name="fastapi"}
{service_name="spring-boot"}
{service_name="compose-example"}
{service_name="pyroscope"}關閉服務:
docker-compose down小結#
從單體式系統的 Profiling、到微服務時代的 Distributed Tracing、再到以 eBPF 鑽進 Kernel 內部直接取資料,每一波都拉低了「看清系統內部運作」的門檻。Pyroscope 把 Continuous Profiling 整合進 Grafana 生態,Beyla 則用 eBPF 讓零侵入的 Auto-Instrumentation 變得可行。對工程師來說,這代表能掌握的細節層級正在持續加深——只要願意理解底層機制,就能更有效地觀察與優化系統。
原文出處#
- 原書/iThome:https://ithelp.ithome.com.tw/articles/10337617