performance - goroutine 堆栈跟踪不完整

标签 performance go

我使用 golang 编写了一个网络应用程序。当它在生产环境中运行时,有一些 goroutines 被阻塞了。以下是信息(使用 pprof 生成):

goroutine 792247 [chan receive, 948 minutes]:
database/sql.(*Tx).awaitDone(0xc4206e2b80)
    /usr/local/go/src/database/sql/sql.go:1440 +0x57
created by database/sql.(*DB).begin
    /usr/local/go/src/database/sql/sql.go:1383 +0x274

goroutine 已经在 channel 上等待了 948 分钟。显然,出了点问题。但堆栈跟踪似乎不完整。我发现错误还不够。 (我想要一些堆栈跟踪从我的程序开始。)

我怎样才能得到这个 goroutine 的完整堆栈跟踪? 或者还有其他方法可以调试此问题吗?

更新:

我看过database/sql/sql.go的源码。结果 database/sql/sql.go:1440 在一个新的 goroutine 中。堆栈跟踪不完整,因为之前的堆栈跟踪属于parent goroutine。

我的问题应该是:有没有更好的方法来调试这个问题?

最佳答案

我认为没有任何方法可以获取父 goroutine 堆栈,而无需手动跟踪每个 go 例程调用并为其生成 id。

在这种特定情况下,很可能您有一个尚未提交或回滚的事务,因为发生错误并且函数在未调用任何一个的情况下过早退出。

避免相同情况的一个好模板是使用“延迟”。

func (s Service) DoSomething() (err error) {
    tx, err := s.db.Begin()
    if err != nil {
        return
    }
    defer func() {
        if err != nil {
            tx.Rollback()
            return
        }
        err = tx.Commit()
    }()
    if _, err = tx.Exec(...); err != nil {
        return
    }
    if _, err = tx.Exec(...); err != nil {
        return
    }
    // ...
    return }

Code Reference

PS:小心错误阴影。

关于performance - goroutine 堆栈跟踪不完整,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43488986/

相关文章:

python - 高效的双for循环

go - gocov不会将完整的测试覆盖率结果上传到codeclimate中

go - 如何搜索 Go 文档?

go - 从 go 调用 fortran 库的最小示例

go - 如何使文件阅读器的功能更有效?

html - 如何使用 Go 发布文件数组?

php - 使用 PHP 将日期从 MySQL 格式转换为 Excel 的最佳性能策略

java - 为什么我的 MINA 应用程序中已用堆总是增加?

java - 使用 Apache Tika + Tesseract 提取扫描 PDF 的速度很慢

sql - 使用JOIN或EXISTS是否可以获得更好的性能?