gops 是怎麼和 Go 的執行時進行互動的?
原文地址:https://medium.com/a-journey-with-go/go-how-does-gops-interact-with-the-runtime-778d7f9d7c18
本文基於 Go 1.13 和 gops 0.3.7.
gops 旨在幫助開發人員診斷 Go 流程並與之互動。它提供了跟蹤執行中的程式幾秒鐘的功能,可以通過獲取 CPU 配置檔案pprof
,甚至可以直接與垃圾收集器進行互動。
發現
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.main
(主 goroutine 的入口)或main.main
(我們程式的入口),則可以將其標記為 Go 程式。
有關符號表的更多資訊,建議您閱讀我的文章 “Go:如何利用符號表”。要了解有關主 goroutine 的更多資訊,建議您閱讀我的文章 “ Go:g0,Special Goroutine”。
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 版本。根據該可執行檔案格式 - ELF,MZ 等- gops 讀取尋找嵌入在二進位制版本 ID 的部分。一旦發現完成,它就可以開始與程式進行互動。
互動
與其他 Go 程式進行互動的唯一條件是確保它們啟動了 gops 代理。該代理是一個簡單的偵聽器,將為 gops 請求提供服務。只需新增以下行即可:
if err:= agent.Listen(agent.Options {}); err!= nil {
log.Fatal(err)
}
然後,具有可用代理的任何程式都可以與 gops 進行互動。這是命令的示例stats
:
# gops stats 168
goroutines: 6210
OS threads: 9
GOMAXPROCS: 2
num CPU: 2
有關更多命令,您可以參考專案文件。如果缺少該代理,則在與該代理進行互動時會收到錯誤訊息:
Couldn't resolve addr or pid 168 to TCPAddress: couldn't get port for PID 168
該錯誤表明 gops 正在通過 TCP 尋找暴露的端點以便與程式進行通訊。讓我們畫出軟體包的工作流程以瞭解其工作原理。
工作流程
gops 與 Go 程式之間的通訊是通過 TCP 和 Go 程式的暴露端點進行的:
分配給每個程式的埠都寫在配置檔案中,例如,path/to/config/{processID}
可以很容易讓 gops 知道暴露的埠。然後,gops 可以將命令標誌傳送到代理將在其中收集資料並進行響應的程式:
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- 程式是怎麼執行的
- 單執行緒的JS如何實現多個互動同時進行執行緒JS
- 執行計劃沒變,執行時快時慢是怎麼回事?
- 程式碼是怎麼執行的?
- Go語言互動執行系統命令Go
- 你們一般都是怎麼進行SQL調優的?MySQL在執行時是如何選擇索引的?MySql索引
- google/gops:一個列出和診斷系統中正在執行Go 程式的命令列工具。Go命令列
- JVM是怎麼和作業系統互動的?JVM作業系統
- JS是怎樣執行的JS
- Webpack 是怎樣執行的?Web
- 大廠是怎麼進行SQL調優的?SQL
- SAP Hybris使用recipe進行安裝時,是如何執行ant命令的?
- 什麼時候執行緒不安全?怎樣做到執行緒安全?怎麼擴充套件執行緒安全的類?執行緒套件
- webpack筆記——hook執行時call的是什麼Web筆記Hook
- V8是怎麼執行JS程式碼的JS
- 一個可執行檔案是怎麼來的
- Webpack 是怎樣執行的?(一)Web
- 為什麼 Go map 和 slice 是非執行緒安全的?Go執行緒
- HttpRunner3的用例是怎麼執行起來的HTTP
- 不使用反射進行C#屬性的執行時動態訪問反射C#
- 什麼是執行緒安全和執行緒不安全執行緒
- JavaScript中執行上下文和執行棧是什麼?JavaScript
- 不要再問我Java程式是怎麼執行的了!Java
- Go的執行原理以及Go的命令Go
- 執行緒池是怎樣工作的?執行緒
- 讀《mysql是怎樣執行的》有感MySql
- 怎麼停止spyder執行的程式
- Laravel 是怎樣防止你的定時任務重複執行的Laravel
- Handler怎麼進行執行緒通訊?Handler原理解讀執行緒
- JavaScript是如何工作的:引擎,執行時和呼叫堆疊的概述!JavaScript
- 什麼是K8S的容器執行時CRI介面?K8S
- 程式執行緒新解:什麼是程式?什麼是執行緒?執行緒
- Spring Boot 到底是怎麼執行的,你知道嗎?Spring Boot
- Spring Boot到底是怎麼執行的,你知道嗎?Spring Boot
- # MySQL server 層和儲存引擎層是怎麼互動資料的?MySqlServer儲存引擎
- React使用axios的post方式和後端進行資料互動ReactiOS後端
- 使用IDEA的go外掛執行某個具體的go test方法,存在10分鐘超時限制,怎麼破?IdeaGo
- 執行長查詢時,怎樣獲取進度?