Go:gops 如何與 runtime 交互?
本文基於 Go 1.13 和 gops 0.3.7。
gops
旨在幫助開發人員診斷 Go 進程並與之交互。它提供了追蹤運行中的程序數秒鐘,通過 pprof
獲取 CPU 的 profile,甚至直接與垃圾回收器交互的能力。
發現
gops
提供了一種發現服務,它可以列出計算機上運行的 Go 進程。不帶參數運行 gops
僅顯示 Go 進程。爲了舉例說明,我啓動了一個程序,該程序計算素數直到一百萬。這是發現程序的輸出:
295 1 gops go1.13 /go/src/github.com/google/gops/gops
168 1 prime-number* go1.13 /go/prime-number/prime-number
gops
發現了上面啓動的程序和它自己的進程。我們需要的僅僅是進程 ID,因此,基於此輸出,我們可以開始與程序進行交互。不過,還是讓我們瞭解一下 gops
如何過濾 Go 進程。
首先,gops
列出所有的進程。接着,對於每個進程,它打開二進制文件讀取符號表:
如果符號表包含了 runtime.man
(主 Goroutine 的入口)或者 main.main
(我們程序的入口),則可以將其標記爲一個 Go 程序。
有關符號表的更多信息,我建議你閱讀我的文章 “Go:如何使用符號表”。瞭解關於主 Goroutine 的更多信息,建議閱讀我的文章 “Go: g0,特殊的 Goroutine[1]”
gops
還會通過讀取符號表的 runtime.buildVersion
來讀取 Go 的版本。然而,由於二進制文件中的符號表可以被剝離,gops
需要另一種方法來檢測 Go 二進制文件。我們用剝離後的二進制文件再試一次:
295 1 gops go1.13 /go/src/..../gops
168 1 prime-number-s* unknown Go version /go/.../prime-number-s
由於缺少符號表,即使程序被正確的標記爲 Go 二進制文件,它也無法檢測 Go 版本。根據可執行文件格式 [2] -- ELF
,MZ
,等等 --gops
會讀取各段來查找嵌在二進制文件中的構建 ID。一旦發現過程結束,它就可以開始與程序交互。
交互
與其他 Go 程序交互的唯一條件是確保它們啓動了 gops
agent。該 agent 是一個簡單的 listener,它將爲 gops 請求提供服務。這很簡單,只需添加以下幾行:
if err := agent.Listen(agent.Options{}); err != nil {
log.Fatal(err)
}
然後,任何啓動了 agent 的程序都可以與 gops
交互。這裏是執行 stats
命令的例子:
# gops stats 168
goroutines: 6210
OS threads: 9
GOMAXPROCS: 2
num CPU: 2
有關更多命令,你可以參考項目的文檔 [3]。如果缺少該 agent,你在與其交互時會收到一個錯誤:
Couldn't resolve addr or pid 168 to TCPAddress: couldn't get port for PID 168
該錯誤表明 gops
在通過 TCP 尋找暴露的 endpoint 以便與程序通信。讓我們畫出這個 package 的工作流來了解它的工作原理:
工作流
gops
通過 TCP 和要讀取的程序暴露的 endpoint 來與其通信:
分配給每個程序的端口都寫在一個配置文件中,例如 path/to/config/{processID}
,這使得 gops
很容易知道暴露的端口。然後,gops
可以將命令標記發送給程序,agent 將會收集數據並響應:
via: https://medium.com/a-journey-with-go/go-how-does-gops-interact-with-the-runtime-778d7f9d7c18
作者:Vincent Blanchon[4] 譯者:DoubleLuck[5] 校對:polaris1119[6]
本文由 GCTT[7] 原創編譯,Go 中文網 [8] 榮譽推出
參考資料
[1]
Go: g0,特殊的 Goroutine: https://medium.com/a-journey-with-go/go-g0-special-goroutine-8c778c6704d8
[2]
可執行文件格式: https://en.wikipedia.org/wiki/Comparison_of_executable_file_formats
[3]
項目的文檔: https://github.com/google/gops#manual
[4]
Vincent Blanchon: https://medium.com/@blanchon.vincent
[5]
DoubleLuck: https://github.com/DoubleLuck
[6]
polaris1119: https://github.com/polaris1119
[7]
GCTT: https://github.com/studygolang/GCTT
[8]
Go 中文網: https://studygolang.com/
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/sxNvANbxXCqzUJOAQemCMA