用golang系统包中的处理方法获取goroutine的调用栈

来源:互联网 发布:淘宝卖鞋子的好店 编辑:程序博客网 时间:2024/06/02 11:21

当golang业务模块发生异常的时候,我们常常需要获取其调用栈来确定发生异常的位置。这里来看看golang系统包中的net/http包(基于1.9版本)中是如何获取goroutine的调用栈的。其源代码如下:

// Serve a new connection.func (c *conn) serve(ctx context.Context) {    c.remoteAddr = c.rwc.RemoteAddr().String()    ctx = context.WithValue(ctx, LocalAddrContextKey, c.rwc.LocalAddr())    defer func() {        if err := recover(); err != nil && err != ErrAbortHandler {            const size = 64 << 10            buf := make([]byte, size)            buf = buf[:runtime.Stack(buf, false)]            c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)        }        if !c.hijacked() {            c.close()            c.setState(c.rwc, StateClosed)        }    }()    ...}

可以看出,获取goroutine调用栈的正确状态为:

            const size = 64 << 10            buf := make([]byte, size)            buf = buf[:runtime.Stack(buf, false)]

buf中存放的就是当前goroutine的调用栈。如果想获取所有goroutine的调用栈,那么把runtime.Stack方法中第二个参数改为true即可。
推荐在所有的接口处都要加上异常处理,并且将调用栈存储起来。虽然可能会稍微牺牲一点点性能。但是服务最重要的参数是业务的正确性和可靠性,在这个基础上再追求高性能。

原创粉丝点击