最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang?并發(fā)下的問題定位及解決方案

 更新時間:2022年03月15日 15:35:02   作者:張叁問  
由于?gin-swagger?是并發(fā)執(zhí)行的,?輸出的日志本身是錯位,這就導致無法定義是哪一個結構體缺少?tag?導致的,這篇文章主要介紹了Golang?并發(fā)下的問題定位及解決方案,需要的朋友可以參考下

問題描述

在使用 gin-swagger 的過程中, 經常會發(fā)生因為缺少 jsontag 而導致的異常。 由于 gin-swagger 是并發(fā)執(zhí)行的, 輸出的日志本身是錯位的。 這就導致無法定義是哪一個結構體缺少 tag 導致的。

一般而言, 這種時候只能一個個點開去檢查。

解決方案

思路 : 要是每行日志帶當前 goroutine_id 的話, 是不是就可以準確定位到報錯的 goroutine 他打印的日志是哪些了呢!

說做就做

實現思路

  • 查看當前日志是怎么打印的

發(fā)現 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 的問題。

調研后發(fā)現了集中常見的獲取 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 ,然后作為日志的前綴。

修改后的日志效果

從中可以看到每行日志開頭,都已經加上了 goroutine_id。 只要使用 panic goroutineid 做一次 grep , 即可篩選出需要的日志了,極大的方便了定位問題。

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

到此這篇關于Golang 并發(fā)下的問題定位的文章就介紹到這了,更多相關Golang并發(fā)問題內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Go語言并發(fā)之原子操作詳解

    Go語言并發(fā)之原子操作詳解

    代碼中的加鎖操作因為涉及內核態(tài)的上下文切換會比較耗時、代價比較高。針對基本數據類型我們還可以使用原子操作來保證并發(fā)安全,本文就來和大家詳細聊聊,需要的可以參考下
    2022-12-12
  • go?zero微服務實戰(zhàn)系服務拆分

    go?zero微服務實戰(zhàn)系服務拆分

    這篇文章主要為大家介紹了go?zero微服務實戰(zhàn)系服務拆分的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • Golang實現密碼加密的示例詳解

    Golang實現密碼加密的示例詳解

    數據庫在存儲密碼時,不能明文存儲,需要加密后存儲,而Golang中的加密算法有很多種,下面小編就來通過簡單的示例和大家簡單聊聊吧
    2023-07-07
  • Go?Excelize?API源碼解析GetSheetFormatPr使用示例

    Go?Excelize?API源碼解析GetSheetFormatPr使用示例

    這篇文章主要為大家介紹了Go?Excelize?API源碼解析GetSheetFormatPr使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-08-08
  • golang如何去除字符串的換行符

    golang如何去除字符串的換行符

    這篇文章主要介紹了golang如何去除字符串的換行符問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • 使用Golang?Validator包實現數據驗證詳解

    使用Golang?Validator包實現數據驗證詳解

    在開發(fā)過程中,數據驗證是一個非常重要的環(huán)節(jié),而golang中的Validator包是一個非常常用和強大的數據驗證工具,提供了簡單易用的API和豐富的驗證規(guī)則,下面我們就來看看Validator包的具體使用吧
    2023-12-12
  • Go語言編程中對文件讀寫的基本方法整理

    Go語言編程中對文件讀寫的基本方法整理

    這篇文章主要介紹了Go語言編程中對文件讀寫的基本方法整理,是Go語言入門學習中的基礎知識,需要的朋友可以參考下
    2015-10-10
  • Golang中的crypto/ecdh包使用詳解

    Golang中的crypto/ecdh包使用詳解

    這篇文章主要給大家詳細介紹了Golang 中的 crypto/ecdh 包,主要包括什么是ECDH 算法和crypto/ecdh 包的使用方法,文中通過代碼示例介紹的非常詳細,需要的朋友可以參考下
    2023-09-09
  • Go語言Gin處理響應方式詳解

    Go語言Gin處理響應方式詳解

    gin框架封裝了常用的數據格式方法響應于客戶端,下面這篇文章主要給大家介紹了關于Go語言Gin處理響應方式的相關資料,文中通過圖文介紹的非常詳細,需要的朋友可以參考下
    2023-01-01
  • go 異常處理panic和recover的簡單實踐

    go 異常處理panic和recover的簡單實踐

    在Go語言中,異常處理主要通過panic和recover這兩個內建函數來實現,本文主要介紹了go異常處理panic和recover的簡單實踐,具有一定的參考價值,感興趣的可以了解一下
    2025-04-04

最新評論

黄大仙区| 休宁县| 虹口区| 双城市| 黄陵县| 五指山市| 阿克| 田阳县| 探索| 柳江县| 皮山县| 道孚县| 张家川| 格尔木市| 文水县| 新竹市| 嘉禾县| 谢通门县| 台北市| 郴州市| 扎赉特旗| 崇阳县| 阳江市| 湘潭市| 分宜县| 武夷山市| 子长县| 郎溪县| 琼结县| 施秉县| 芦山县| 菏泽市| 伊金霍洛旗| 合川市| 方城县| 龙岩市| 新兴县| 彭山县| 温州市| 积石山| 西乌珠穆沁旗|