Golang 并发下的问题定位及解决方案


Posted in Golang onMarch 16, 2022

问题描述

在使用 gin-swagger 的过程中, 经常会发生因为缺少 jsontag 而导致的异常。 由于 gin-swagger 是并发执行的, 输出的日志本身是错位的。 这就导致无法定义是哪一个结构体缺少 tag 导致的。

Golang 并发下的问题定位及解决方案

一般而言, 这种时候只能一个个点开去检查。

解决方案

思路 : 要是每行日志带当前 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-swagger main.go 源码, 修改 log Write 的实现

修改前

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 ,然后作为日志的前缀。

修改后的日志效果

Golang 并发下的问题定位及解决方案

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

Golang 并发下的问题定位及解决方案

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

Golang 并发下的问题定位及解决方案

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

Golang 相关文章推荐
Go缓冲channel和非缓冲channel的区别说明
Apr 25 Golang
golang通过递归遍历生成树状结构的操作
Apr 28 Golang
golang 如何用反射reflect操作结构体
Apr 28 Golang
Golang 使用Map实现去重与set的功能操作
Apr 29 Golang
Go 自定义package包设置与导入操作
May 06 Golang
Go Plugins插件的实现方式
Aug 07 Golang
Golang中channel的原理解读(推荐)
Oct 16 Golang
golang生成vcf通讯录格式文件详情
Mar 25 Golang
简单聊聊Golang中defer预计算参数
Mar 25 Golang
Golang jwt身份认证
Apr 20 Golang
GO中sync包自由控制并发示例详解
Aug 05 Golang
Go中使用gjson来操作JSON数据的实现
Aug 14 Golang
如何利用golang运用mysql数据库
深入理解go缓存库freecache的使用
Feb 15 #Golang
Go语言读取txt文档的操作方法
Jan 22 #Golang
一文搞懂Golang 时间和日期相关函数
Go语言基础切片的创建及初始化示例详解
Nov 17 #Golang
Go语言基础map用法及示例详解
Nov 17 #Golang
Go语言基础函数基本用法及示例详解
Nov 17 #Golang
You might like
WML,Apache,和 PHP 的介绍
2006/10/09 PHP
第二章 PHP入门基础之php代码写法
2011/12/30 PHP
php+lottery.js实现九宫格抽奖功能
2019/07/21 PHP
Laravel定时任务的每秒执行代码
2019/10/22 PHP
IE autocomplete internet explorer's autocomplete
2007/06/30 Javascript
js cookies 常见网页木马挂马代码 24小时只加载一次
2009/04/13 Javascript
IE和FireFox(FF)中js和css的不同
2009/04/13 Javascript
javascript学习笔记(八) js内置对象
2012/06/19 Javascript
表单序列化与jq中的serialize使用示例
2014/02/21 Javascript
js创建一个input数组并绑定click事件的方法
2014/06/12 Javascript
基于javascript实现样式清新图片轮播特效
2016/03/30 Javascript
CascadeView级联组件实现思路详解(分离思想和单链表)
2016/04/12 Javascript
easyUI实现(alert)提示框自动关闭的实例代码
2016/11/07 Javascript
Angular.js中window.onload(),$(document).ready()的写法浅析
2017/09/28 Javascript
Angularjs按需查询实例代码
2017/10/30 Javascript
搭建vue开发环境
2018/07/19 Javascript
JavaScript封装的常用工具类库bee.js用法详解【经典类库】
2018/09/03 Javascript
jQuery添加新内容的四个常用方法分析【append,prepend,after,before】
2019/03/19 jQuery
JS+html5实现异步上传图片显示上传文件进度条功能示例
2019/11/09 Javascript
[02:18]《我与DAC》之工作人员:为了热爱DOTA2的玩家们
2018/03/28 DOTA
videocapture库制作python视频高速传输程序
2013/12/23 Python
深入理解python多进程编程
2016/06/12 Python
Python字符串匹配之6种方法的使用详解
2019/04/08 Python
利用python将图片版PDF转文字版PDF
2019/05/03 Python
python对矩阵进行转置的2种处理方法
2019/07/17 Python
django restframework serializer 增加自定义字段操作
2020/07/15 Python
Python TestSuite生成测试报告过程解析
2020/07/23 Python
使用Python解析Chrome浏览器书签的示例
2020/11/13 Python
优秀信贷员先进事迹
2014/01/31 职场文书
完美主义个人的自我评价
2014/02/17 职场文书
《伯牙绝弦》教学反思
2014/03/02 职场文书
给全校老师的建议书
2014/03/13 职场文书
学校社团活动总结
2015/05/07 职场文书
立项申请报告范本
2015/05/15 职场文书
2016年公司新年寄语
2015/08/17 职场文书
element tree树形组件回显数据问题解决
2022/08/14 Javascript