You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取Docker容器中Go入口进程的Goroutine Dump?

解决容器内Go进程Goroutine Dump无法获取的问题

以下是几种可行的方案,按推荐优先级排序:

1. 集成pprof HTTP接口(最稳妥)

在Go程序中添加pprof支持,无需发送QUIT信号即可获取dump,进程不会终止:

  • 在代码中导入pprof包并启动HTTP服务:
    import _ "net/http/pprof"
    import "log"
    import "net/http"
    
    func main() {
        // 启动pprof监听,端口可自定义
        go func() {
            if err := http.ListenAndServe("0.0.0.0:6060", nil); err != nil {
                log.Printf("pprof server failed: %v", err)
            }
        }()
        // 你的业务逻辑代码
    }
    
  • 确保docker-compose配置中容器的6060端口(或自定义端口)未被限制,然后在宿主机执行:
    docker exec <container-id> curl http://localhost:6060/debug/pprof/goroutine?debug=2
    
    直接获取完整的Goroutine Dump内容,进程和容器都不会停止。

2. 重定向Go进程的stderr到文件

启动Go程序时,将标准错误输出重定向到容器内的持久化文件,这样即使进程终止,文件依然存在:

  • 修改docker-compose中Go服务的启动命令,比如:
    services:
      go-app:
        command: ./your-go-binary 2>/app/goroutine_dump.log
        # 其他配置...
    
  • 当需要获取dump时,进入容器发送QUIT信号:
    docker exec -it <container-id> kill -QUIT <pid>
    
  • 即使容器停止,也可以通过docker cp将文件拷出:
    docker cp <container-id>:/app/goroutine_dump.log ./local_dump.log
    

3. 通过docker logs捕获dump

如果Go进程的stderr默认输出到容器日志(大部分情况都是如此),发送QUIT信号后,dump会被写入容器日志,即使容器停止也能读取:

  • 发送QUIT信号:
    docker exec <container-id> kill -QUIT <pid>
    
  • 容器停止后,执行以下命令查看并提取日志中的dump:
    docker logs <container-id> | grep -A 1000 "goroutine stack traces:"
    

4. 实时捕获dump输出

无需进入容器,直接通过docker exec组合命令发送信号并立即捕获输出:

docker exec <container-id> sh -c 'kill -QUIT <pid>; sleep 0.5; cat /proc/<pid>/fd/2'

注:这个方法依赖进程在退出前能将dump写入stderr,若进程退出过快可能失效,建议优先用前三种方法。

内容的提问来源于stack exchange,提问作者TieDad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:05:15