29

gops 是怎么和 Go 的运行时进行交互的?

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzA4ODg0NDkzOA%3D%3D&%3Bmid=2247487850&%3Bidx=1&%3Bsn=9ac021cf669a5542cfefe90d81b8114a
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

ZbqEBry.png!web

原文地址: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 进程。为了举例说明,我启动了一个程序,该程序可以计算高达一百万的素数。这是流程发现的输出:

gops 看到程序启动以及它自己的过程。基于此输出,我们唯一需要的是进程 ID 就可以开始与程序进行交互。但是,让我们了解 gops 是如何只过滤 Go 进程。

首先,gops 列出所有过程。然后,对于每个进程,它将打开二进制文件以读取其符号表:

yuUJN3F.png!web

如果符号表包含 runtime.main (主 goroutine 的入口)或  main.main (我们程序的入口),则可以将其标记为 Go 程序。

有关符号表的更多信息,建议您阅读我的文章 “Go:如何利用符号表”。要了解有关主 goroutine 的更多信息,建议您阅读我的文章 “ Go:g0,Special Goroutine”。

gops 也会通过之前的符号表里面的 runtime.buildVersion 获取使用的 Go 版本。但是,由于可以从二进制文件中删除符号表,因此 gops 需要另一种方法来检测 Go 二进制文件。让我们用剥离后的二进制文件再试一次:

如果程序正确地标记为 Go 二进制文件,则由于缺少符号表,因此无法再检测 Go 版本。根据该可执行文件格式 - ELF,MZ 等 - gops 读取寻找嵌入在二进制版本 ID 的部分。一旦发现完成,它就可以开始与程序进行交互。

交互

与其他 Go 程序进行交互的唯一条件是确保它们启动了 gops 代理。该代理是一个简单的侦听器,将为 gops 请求提供服务。只需添加以下行即可:

然后,具有可用代理的任何程序都可以与 gops 进行交互。这是命令的示例 stats

有关更多命令,您可以参考项目文档。如果缺少该代理,则在与该代理进行交互时会收到错误消息:

该错误表明 gops 正在通过 TCP 寻找暴露的端点以便与程序进行通信。让我们画出软件包的工作流程以了解其工作原理。

工作流程

gops 与 Go 程序之间的通信是通过 TCP 和 Go 程序的暴露端点进行的:

mqYnMje.png!web

分配给每个程序的端口都写在配置文件中,例如, path/to/config/{processID} 可以很容易让 gops 知道暴露的端口。然后,gops 可以将命令标志发送到代理将在其中收集数据并进行响应的程序:

NzUrQjb.png!web

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK