您现在的位置是:网站首页> 编程资料编程资料
Golang 并发下的问题定位及解决方案_Golang_
                     2023-05-26
                493人已围观
                
                2023-05-26
                493人已围观
            
简介 Golang 并发下的问题定位及解决方案_Golang_
问题描述
在使用 gin-swagger 的过程中, 经常会发生因为缺少 json 等 tag 而导致的异常。 由于 gin-swagger 是并发执行的, 输出的日志本身是错位的。 这就导致无法定义是哪一个结构体缺少 tag 导致的。

一般而言, 这种时候只能一个个点开去检查。
解决方案
思路 : 要是每行日志带当前 goroutine_id 的话, 是不是就可以准确定位到报错的 goroutine 他打印的日志是哪些了呢!
说做就做
实现思路
- 查看当前日志是怎么打印的
发现 gin-swagger 日志直接调用的 golang 的标准库 log
由于没有对log初始化, 所以默认使用的是 stdout 。
log.Printf("Picking operation from %s\n", aurora.Blue(funType.FullName()))- 如果想要给日志中添加 goroutine_id的话, 就需要在调用log.Printf的时候获取当前goroutine的 id , 所以首先要解决的是怎么获取goroutine_id的问题。
调研后发现了集中常见的获取 goroutine_id 的方法:
2.1 通过栈信息解析后获取
func GetGID() uint64 { b := make([]byte, 64) b = b[:runtime.Stack(b, false)] b = bytes.TrimPrefix(b, []byte("goroutine ")) b = b[:bytes.IndexByte(b, ' ')] n, _ := strconv.ParseUint(string(b), 10, 64) return n }2.2 修改 Go 源码获取
# src/runtime/runtime2.go func Goid() int64 { _g_ := getg() return _g_.goid }2.3 通过 CGO 获取
文件 id.c
#include "runtime.h" int64 ·Id(void) { return g->goid; }文件 id.go
package id func Id() int64
另外还可以通过汇编获取 goroutine_id
由于go的版本不同,goroutine的结构也可能不同, 所以此处我直接调用一个开源实现:
https://github.com/petermattis/goid
- 修改 gin-swaggermain.go源码, 修改logWrite的实现
修改前
func main() { cmd.Execute() }修改后
type Out os.File func (o Out) Write(b []byte) (int, error) { prefix := fmt.Sprintf("gid-%d: ", goid.Get()) all := make([]byte, len(b)+len(prefix)) all = []byte(prefix) all = append(all, b...) f := os.File(o) return f.Write(all) } func main() { var out Out out = Out(os.Stdout) log.SetOutput(out) cmd.Execute()这样修改后,每次 gin-swagger 调用 log 打印日志都时候, 都会使用我定义的 Write 方法, Write 方法中每次打印前都会先查询出当前的 goroutine_id ,然后作为日志的前缀。
修改后的日志效果

从中可以看到每行日志开头,都已经加上了 goroutine_id。 只要使用 panicgoroutine 的 id 做一次 grep , 即可筛选出需要的日志了,极大的方便了定位问题。

cat /tmp/gin-swagger.log | grep 7647

到此这篇关于Golang 并发下的问题定位的文章就介绍到这了,更多相关Golang并发问题内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
 
                                
                                                         
                                
                                                         
                                
                                                         
 
    