前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >超好用的golang工具分享

超好用的golang工具分享

原创
作者头像
于顾而言SASE
发布2024-03-21 10:27:23
800
发布2024-03-21 10:27:23
举报
文章被收录于专栏:golang与云原生golang与云原生

go-callvis-代码调用关系的可视化工具

go-callvis是一个代码调用关系的可视化工具,它可以帮助我们了解指定项目代码的结构,以达到更快的理解代码意图的目的。

工具使用简单,步骤如下:

代码语言:javascript
复制
// 1. 安装
git clone https://github.com/ofabry/go-callvis.git
cd go-callvis && make install

// 2. 以著名golang开源项目bigcache 的main函数为入口,分析代码调用关系(不打开浏览器 | 忽略标准库的方法)
go-callvis -skipbrowser -nostd ./server/

// 3. 访问http://localhost:7878查看调用关系矢量图

调用关系矢量图怎么看,一共分为三个部分:

Packages / Types(包)

Represents

Style

focused(需要关注的)

blue color(蓝色)

stdlib(标准库)

green color(绿色)

other(其他包)

yellow color(黄色)

Functions / Methods(函数方法)

Represents

Style

exported(导出的包)

bold border(粗边框)

unexported(未导出包)

normal border(正常边框)

anonymous(匿名包)

dotted border(虚线边框)

Calls(调用)

Represents

Style

internal(内部)

black color(黑色)

external(外部)

brown color(棕色)

static(静态函数)

solid line(实线)

dynamic(动态函数)

dashed line(虚线)

regular(常规函数)

simple arrow(简单箭头)

concurrent(协程)

arrow with circle(箭头带圆圈)

deferred(defer)

arrow with diamond(箭头带菱形)

gotests-自动生成单测用例框架

gotests工具可以帮我们自动生成单测用例框架,这样以来,我们只需要关注需要测试的业务代码逻辑即可,省去了大量的拷贝复制的重复劳动。

gotest工具使用也是十分方便,可以直接安装(go get -u github.com/cweill/gotests/...)后用命令行($ gotests [options] PATH ...)的方式,或者也可以作为IDE的插件直接使用,如Emacs,Vim,Atom Editor,Visual Studio Code, andIntelliJ Goland. 这里以VS Code为例:

代码语言:javascript
复制
// 一个简单工厂模式代码实现

package simplefactory

import "fmt"

//API is interface
type API interface {
	Say(name string) string
}

//NewAPI return Api instance by type
func NewAPI(t int) API {
	if t == 1 {
		return &hiAPI{}
	} else if t == 2 {
		return &helloAPI{}
	}
	return nil
}

//hiAPI is one of API implement
type hiAPI struct{}

//Say hi to name
func (*hiAPI) Say(name string) string {
	return fmt.Sprintf("Hi, %s", name)
}

//HelloAPI is another API implement
type helloAPI struct{}

//Say hello to name
func (*helloAPI) Say(name string) string {
	return fmt.Sprintf("Hello, %s", name)
}

自动生成的测试用例框架,如下:

代码语言:javascript
复制
PS D:\code\golang-design-pattern\00_simple_factory> gotests.exe  -all .\simple.go
Generated TestNewAPI
Generated Test_hiAPI_Say
Generated Test_helloAPI_Say
package simplefactory

import (
        "reflect"
        "testing"
)

func TestNewAPI(t *testing.T) {
        type args struct {
                t int
        }
        tests := []struct {
                name string
                args args
                want API
        }{
                // TODO: Add test cases.
        }
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        if got := NewAPI(tt.args.t); !reflect.DeepEqual(got, tt.want) {
                                t.Errorf("NewAPI() = %v, want %v", got, tt.want)
                        }
                })
        }
}

func Test_hiAPI_Say(t *testing.T) {
                })
        }
}

func Test_helloAPI_Say(t *testing.T) {
        type args struct {
                name string
        }
        tests := []struct {
                name string
                h    *helloAPI
                args args
                want string
        }{
                // TODO: Add test cases.
        }
        for _, tt := range tests {
                t.Run(tt.name, func(t *testing.T) {
                        h := &helloAPI{}
                        if got := h.Say(tt.args.name); got != tt.want {
                                t.Errorf("helloAPI.Say() = %v, want %v", got, tt.want)
                        }
                })
        }
}
PS D:\code\golang-design-pattern\00_simple_factory>

go-multierror-多错误管理

在关于使用 Go 语言的时候,开发者面对最大的挑战的年度调查中,错误(error)管理总是能引起很多争论。在并发环境处理 error 的场景下,或者在同一个 goroutine 中合并多个错误的场景下,Go 提供了很不错的包可以让多个错误的处理变得简单:来看看如何合并由单个 goroutine 生成的多个 error。

go-multierror提供了常用的多错误管理四种方式:

Building a list of errors / Accessing the list of errors / Checking for an exact error value

构建错误返回列表 / 访问误返回列表 / 检查错误列表中是否包含某个错误

代码语言:javascript
复制
package main

import (
    "fmt"
    "errors"
    multierror"github.com/hashicorp/go-multierror"
)

func step1() error {
    return errors.New("xhihu")
}

func step2() error {
    return errors.New("yhihu")
}


func main() {
    var result error

    if err := step1(); err != nil {
        result = multierror.Append(result, err)
    }
    if err := step2(); err != nil {
        result = multierror.Append(result, err)
    }

    fmt.Printf(result.Error())

    if merr, ok := result.(*multierror.Error); ok {
        // Use merr.Errors
        // merr.Errors -> []error    
    }

    if errors.Is(result, os.ErrNotExist) {
	// err contains os.ErrNotExist
    }
    return
}

Customizing the formatting of the errors / 自定义多错误时显示的整体的打印信息

代码语言:javascript
复制
var result *multierror.Error

// ... accumulate errors here, maybe using Append

if result != nil {
	result.ErrorFormat = func([]error) string {
		return "errors!"
	}
}

goleak-内存泄漏检查

goroutine 泄漏会导致内存中存活的 goroutine 数量不断上升,直到把主机的CPU和内存全部吃爆,最终以服务宕机为止。所以,我们会想到有没有一种方法,可以在代码部署之前,来检查程序中是否存在goroutine 泄漏。

Uber 公司的 Go 团队在 GitHub 开源了他们的goroutine 泄漏检测器出来,一个与单元测试结合使用的工具。 goleak 可以监控当前测试代码中泄漏的 goroutine。下面有一个 goroutine 泄漏的例子:

代码语言:javascript
复制
//demo.go
func leak() error {
    go func() {
        time.Sleep(time.Minute)
    }()

    return nil
}

//demo_test.go
func TestLeakFunction(t *testing.T) {
    defer goleak.VerifyNone(t)

    if err := leak(); err != nil {
        t.Fatal("error not expected")
    }
}

用例直接报错了,从报错信息中我们可以看到泄露的goroutine 的堆栈信息,以及 goroutine 的状态。

pprof性能分析+火焰图

Pprof是一个用于采样数据可视化和分析的工具。主要分析服务运行过程产生的:阻塞同步的堆栈信息,所有的goroutine堆栈信息,活动对象的内存分配信息,互斥锁的竞争持有者的堆栈,默认进行30s的CPU采样信息,查看创建新OS线程的堆栈信息等等。

我们可以利用prof进行性能监控,且可以生成监控信息文件,方便后续分析性能瓶颈或者是内存泄漏情况。

代码语言:javascript
复制
package main

import (
    "fmt"
    "time"
    "log"
    "net/http"
    _ "net/http/pprof"
    "os"
    "runtime"
)

func alloc(outCh chan<- int) {
        buf := make([]byte, 1024)
        outCh <- 0
}

func Leak() {
        outCh := make(chan int)

        go func() {
                if false {
                        <-outCh
                }
                select {}
        }()

        tick := time.Tick(time.Second / 100)
        i := 0
        for range tick {
                i++
                fmt.Println(i)
                //一直分配内存,不释放放
                go alloc(outCh)
}

func main() {
    log.SetFlags(log.Lshortfile | log.LstdFlags)
    log.SetOutput(os.Stdout)

    runtime.GOMAXPROCS(1)
    runtime.SetMutexProfileFraction(1)
    runtime.SetBlockProfileRate(1)

    // 需要性能分析的业务逻辑
    go Leak()

    go func() {
        // 通过http://locahost:6060/debug/pprof进行查看相关的监控信息文件
        if err := http.ListenAndServe(":6060", nil); err != nil {
            log.Fatal(err)
        }
        os.Exit(0)
    }()

    select{}
}


1. go build  prof_demo.go

2. ./prof_demo

3. 手动登陆浏览器,通过http://locahost:6060/debug/pprof进行查看相关的监控信息文件

4. go install github.com/google/pprof@latest

5. yum install graphviz

// 查看火焰图
6. pprof -http=:6061  http://192.168.159.140:6060/debug/pprof/profile

jsoniter-高性能json序列化工具

go语言多数用于云原生中的网咯服务,因此一个常见的场景就是数据的序列化和反序列化,一般都是利用json进行。这里推荐采用jsoniter替换掉go原生encoding/json,两者接口一致,但jsoniter的性能远远超过encoding/json,Benchmark详见如下:

ns/op

allocation bytes

allocation times

std decode

35510 ns/op

1960 B/op

99 allocs/op

easyjson decode

8499 ns/op

160 B/op

4 allocs/op

jsoniter decode

5623 ns/op

160 B/op

3 allocs/op

代码语言:javascript
复制
import jsoniter "github.com/json-iterator/go"

var json = jsoniter.ConfigCompatibleWithStandardLibrary
json.Marshal(&data)

json.Unmarshal(input, &data)

Reference

Go代码调用链路可视化工具—go-callvis - 知乎 (zhihu.com)

GoTests工具自动化test使用 - 掘金 (juejin.cn)

Go: Multiple Errors Management. Error management in Go is always prone… | by Vincent Blanchon | A Journey With Go | Medium

Fastest JSON parser ever (jsoniter.com)

Go:多错误管理 - Go语言中文网 - Golang中文社区 (studygolang.com)

GitHub - hashicorp/go-multierror: A Go (golang) package for representing a list of errors as a single error

Go: Goroutine 泄漏检查器 - Go语言中文网 - Golang中文社区 (studygolang.com)

golang性能优化之pprof及其火焰图 - 简书 (jianshu.com)

Golang-PProf之性能剖析_-Xx.。的博客-CSDN博客_golang pprof allocs 解释

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • go-callvis-代码调用关系的可视化工具
  • gotests-自动生成单测用例框架
  • go-multierror-多错误管理
  • goleak-内存泄漏检查
  • pprof性能分析+火焰图
  • jsoniter-高性能json序列化工具
  • Reference
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档