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 相关文章推荐
golang 实现两个结构体复制字段
Apr 28 Golang
golang 实现Location跳转方式
May 02 Golang
解决golang结构体tag编译错误的问题
May 02 Golang
golang 比较浮点数的大小方式
May 02 Golang
goland 设置project gopath的操作
May 06 Golang
golang 实现时间戳和时间的转化
May 07 Golang
Golang 并发下的问题定位及解决方案
Mar 16 Golang
如何解决goland,idea全局搜索快捷键失效问题
Apr 03 Golang
golang使用map实现去除重复数组
Apr 14 Golang
Golang 字符串的常见操作
Apr 19 Golang
Go语言测试库testify使用学习
Jul 23 Golang
Go结合Gin导出Mysql数据到Excel表格
Aug 05 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
漫荒推荐:画风超赞的国风漫画推荐 超长假期不无聊
2020/03/08 国漫
新版PHP极大的增强功能和性能
2006/10/09 PHP
php使用ob_flush不能每隔一秒输出原理分析
2015/06/02 PHP
浅谈mysql_query()函数的返回值问题
2016/09/05 PHP
让您的菜单不离网站
2006/10/03 Javascript
js 实现无干扰阴影效果 简单好用(附文件下载)
2009/12/27 Javascript
JQuery从头学起第三讲
2010/07/06 Javascript
使用jquery的ajax需要注意的地方dataType的设置
2013/08/12 Javascript
Javascript中3个需要注意的运算符
2015/04/02 Javascript
JavaScript脚本判断蜘蛛来源的方法
2015/09/22 Javascript
jquery插件jquery.confirm弹出确认消息
2015/12/22 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记9)
2015/12/24 Javascript
HTML5游戏引擎LTweenLite实现的超帅动画效果(附demo源码下载)
2016/01/26 Javascript
基于javascript实现样式清新图片轮播特效
2016/03/30 Javascript
基于Node.js + WebSocket打造即时聊天程序嗨聊
2016/11/29 Javascript
JavaScript Date 知识浅析
2017/01/29 Javascript
微信小程序实战之上拉(分页加载)效果(2)
2017/04/17 Javascript
微信小程序 蓝牙的实现实例代码
2017/06/27 Javascript
Vue组件和Route的生命周期实例详解
2018/02/10 Javascript
Vue使用vue-area-linkage实现地址三级联动效果的示例
2018/06/27 Javascript
mac上配置Android环境变量的方法
2018/07/08 Javascript
使用post方法实现json往返传输数据的方法
2019/03/30 Javascript
Js利用正则表达式去除字符串的中括号
2020/11/23 Javascript
Python实现接受任意个数参数的函数方法
2018/04/21 Python
python 将数据保存为excel的xls格式(实例讲解)
2018/05/03 Python
python3爬取torrent种子链接实例
2020/01/16 Python
详解用Python调用百度地图正/逆地理编码API
2020/07/02 Python
python缩进长度是否统一
2020/08/02 Python
意大利时尚精品店:Nugnes 1920
2020/02/10 全球购物
Nasty Gal英国:美国女性服饰销售网站
2021/03/02 全球购物
《我的伯父鲁迅先生》教学反思
2014/02/12 职场文书
公休请假条
2014/04/11 职场文书
反邪教警示教育方案
2014/05/13 职场文书
员工安全生产承诺书
2014/05/22 职场文书
学长教您写论文:经验总结
2019/07/09 职场文书
JavaScript实现简单图片切换
2021/04/29 Javascript