goland的工具链
参考: https://studygolang.com/articles/18656?fr=sidebar
http://c.biancheng.net/view/124.html
go build 最常用的编译go 文件
可以夸平台使用: env GOOS=linux GOARCH=amd64 go build
go install : 本地打包编译命令
go install 与go build的区别: install 编译后会将输出文件打包成库 放到pkg 目录下
go get 通常获取第三方的包。 通常会从git repo上pull下来最新的版本
go test
特殊:不需要 main() 作为函数入口。所有在以_test
结尾的源码内以Test
开头的函数会自动被执行
- 每一个test文件需要import一个testing
- 默认的情况下,
go test
命令不需要任何的参数,它会自动把你源码包下面所有 test 文件测试完毕,当然你也可以带上参数。 - 这里介绍几个常用的参数:
- -bench regexp 执行相应的 benchmarks,例如 -bench=.;
- -cover 开启测试覆盖率;
- -run regexp 只运行 regexp 匹配的函数,例如 -run=Array 那么就执行包含有 Array 开头的函数;
- -v 显示测试的详细命令。
-
package main import ( "fmt" "testing" ) /*test 测试,可以没有main 作为函数入口*/ func TestHelloWord(t *testing.T) { fmt.Println("测试单元") t.Log("Hello word") } /*执行方式 go test helloworld_test.go*/ /*可以多个测试函数*/ func TestHelloWord2(t *testing.T) { fmt.Println("测试单元") t.Log("Hello word") } /*默认多个测试案例一次测试,如果想指定特定函数 可以执行 go test run TestHelloWord2 helloword_test.go*/ /*终止测试单元*/ func TestFailNow(t *testing.T) { t.Log("stop2 Hello word") t.FailNow() t.Log("stop2 Hello word") } /*标记错误不终止*/ func TestFail(t *testing.T) { fmt.Println("before fail") t.Fail() fmt.Println("after fail") } /*一下是基准测试用例基准测试——获得代码内存占用和运行效率的性能数据*/ /*开启基准测试 go test -v -bench=. helloword_test.go 第 1 行的-bench=.表示运行 benchmark_test.go 文件里的所有基准测试,和单元测试中的-run类似。 第 4 行中显示基准测试名称,2000000000 表示测试的次数,也就是 testing.B 结构中提供给程序使用的 N。 “0.33 ns/op”表示每一个操作耗费多少时间(纳秒)。 */ /*如果bench 和test 在同一个测试文件中,执行某个test 或者指定某个bench执行的时候,需要按照一下方式 go test -v helloword_test.go -test.bench Add -test.run Add go test -v helloword_test.go -test.run TestHelloWord2 */ func Benchmark_Add(b *testing.B) { var n int for i := 0; i < b.N; i++ { n++ } } /*内存测试 go test -v -bench=Alloc -benchmem helloword_test.go 由于和test在同一个文件中 可用go test -v -bench=Alloc -benchmem helloword_test.go -test.bench Alloc -test.run Alloc 执行 第 1 行的代码中-bench后添加了 Alloc,指定只测试 Benchmark_Alloc() 函数。 第 4 行代码的“16 B/op”表示每一次调用需要分配 16 个字节,“2 allocs/op”表示每一次调用有两次分配。 */ func Benchmark_Alloc(b *testing.B) { for i := 0; i < b.N; i++ { fmt.Sprintf("%d", i) } }
-
gofmt : 代码格式工具,针对代码格式统一
进行代码格式化,具体方法是,点击Preferences -> Tools -> File Watchers,点加号添加一个go fmt模版,Goland中预置的go fmt模版使用的是go fmt命令,将其替换为gofmt,然后在参数中增加-l -w -s参数,启用代码简化功能。添加配置后,保存源码时,goland就会执行代码格式化了。
golint: 对代码质量检查 指出不规范之处,会给出一些指导: 具体看事例
golint 文件名或者目录
变量名规范 变量的声明,像var str string = "test",会有警告,应该var str = "test" 大小写问题,大写导出包的要有注释 x += 1 应该 x++ 等等……
3、性能检测
top top $N 用于显示前N个占用CPU最高的函数, top \$N –cum表示前N个累积占用CPU最高的函数。(累积,是指采样的栈里面存在这个函数,也就是它的整个子调用链的占有时间都累加起来 )
list list $function 可以展示这个function中每一行占用的情况。
Go语言工具链中的 go pprof 可以帮助开发者快速分析及定位各种性能问题,如 CPU 消耗、内存分配及阻塞分析。
性能分析首先需要使用 runtime.pprof 包嵌入到待分析程序的入口和结束处。runtime.pprof 包在运行时对程序进行每秒 100 次的采样,最少采样 1 秒。然后将生成的数据输出,让开发者写入文件或者其他媒介上进行分析。
go pprof 工具链配合 Graphviz 图形化工具可以将 runtime.pprof 包生成的数据转换为 PDF 格式,以图片的方式展示程序的性能分析结果。
安装第三方图形化显式分析数据工具(Graphviz)
Graphviz 是一套通过文本描述的方法生成图形的工具包。描述文本的语言叫做 DOT。
在 www.graphviz.org 网站可以获取到最新的 Graphviz 各平台的安装包。
CentOS 下,可以使用 yum 指令直接安装:
$ yum install graphiviz
安装第三方性能分析来分析代码包
runtime.pprof 提供基础的运行时分析的驱动,但是这套接口使用起来还不是太方便,例如:
- 输出数据使用 io.Writer 接口,虽然扩展性很强,但是对于实际使用不够方便,不支持写入文件。
- 默认配置项较为复杂。
很多第三方的包在系统包 runtime.pprof 的技术上进行便利性封装,让整个测试过程更为方便。这里使用 github.com/pkg/profile 包进行例子展示,使用下面代码安装这个包:
$ go get github.com/pkg/profile
性能分析代码
下面代码故意制造了一个性能问题,同时使用 github.com/pkg/profile 包进行性能分析。
- package main
- import (
- "github.com/pkg/profile"
- "time"
- )
- func joinSlice() []string {
- var arr []string
- for i := 0; i < 100000; i++ {
- // 故意造成多次的切片添加(append)操作, 由于每次操作可能会有内存重新分配和移动, 性能较低
- arr = append(arr, "arr")
- }
- return arr
- }
- func main() {
- // 开始性能分析, 返回一个停止接口
- stopper := profile.Start(profile.CPUProfile, profile.ProfilePath("."))
- // 在main()结束时停止性能分析
- defer stopper.Stop()
- // 分析的核心逻辑
- joinSlice()
- // 让程序至少运行1秒
- time.Sleep(time.Second)
- }
代码说明如下:
- 第 4 行,引用 github.com/pkg/profile 第三方包封装。
- 第 14 行,为了进行性能分析,这里在已知元素大小的情况下,还是使用 append() 函数不断地添加切片。性能较低,在实际中应该避免,这里为了性能分析,故意这样写。
- 第 22 行,使用 profile.Start 调用 github.com/pkg/profile 包的开启性能分析接口。这个 Start 函数的参数都是可选项,这里需要指定的分析项目是 profile.CPUProfile,也就是 CPU 耗用。profile.ProfilePath(".") 指定输出的分析文件路径,这里指定为当前文件夹。profile.Start() 函数会返回一个 Stop 接口,方便在程序结束时结束性能分析。
- 第 25 行,使用 defer,将性能分析在 main() 函数结束时停止。
- 第 28 行,开始执行分析的核心。
- 第 31 行,为了保证性能分析数据的合理性,分析的最短时间是 1 秒,使用 time.Sleep() 在程序结束前等待 1 秒。如果你的程序默认可以运行 1 秒以上,这个等待可以去掉。
性能分析需要可执行配合才能生成分析结果,因此使用命令行对程序进行编译,代码如下:
$ go build -o cpu cpu.go
$ ./cpu
$ go tool pprof --pdf cpu cpu.pprof > cpu.pdf
代码说明如下:
- 第 1 行将 cpu.go 编译为可执行文件 cpu。
- 第 2 行运行可执行文件,在当前目录输出 cpu.pprof 文件。
- 第 3 行,使用 go tool 工具链输入 cpu.pprof 和 cpu 可执行文件,生成 PDF 格式的输出文件,将输出文件重定向为 cpu.pdf 文件。这个过程中会调用 Graphviz 工具,Windows 下需将 Graphviz 的可执行目录添加到环境变量 PATH 中。
最终生成 cpu.pdf 文件,使用 PDF 查看器打开文件,观察后发现下图所示的某个地方可能存在瓶颈。
图:性能分析
图中的每一个框为一个函数调用的路径,第 3 个方框中 joinSlice 函数耗费了 50% 的 CPU 时间,存在性能瓶颈。重新优化代码,在已知切片元素数量的情况下直接分配内存,代码如下:
- func joinSlice() []string {
- const count = 100000
- var arr []string = make([]string, count)
- for i := 0; i < count; i++ {
- arr[i] = "arr"
- }
- return arr
- }
代码说明如下:
- 第 5 行,将切片预分配 count 个数量,避免之前使用 append() 函数的多次分配。
- 第 8 行,预分配后,直接对每个元素进行直接赋值。
重新运行上面的代码进行性能分析,最终得到的 cpu.pdf 中将不会再有耗时部分。
1、安装 如果想安装多个版本的go 本实力中使用的是 gvm工具
bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
使用 gvm version 校验是否安装成功
如果不成功,需要配置host 文件
2、查看已经安装的版本有哪些?
gvm list
查看所有的版本
gvm listall
安装最新版本 目前是1.16
gvm install go1.16 -B
gvm 需要用那个版本 直接执行
gvm use go1.16
goclt 代码管理控制工具
goctl --help
rpc 的创建https://www.yuque.com/tal-tech/go-zero/zlc5xq
启动rpc 服务端需要依赖 etcd
etcd是CoreOS团队于2013年6月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库。etcd内部采用raft
协议作为一致性算法,etcd基于Go语言实现。
需要先启动etcd 直接执行 etcd
如果没有安装,先安装 brew install etcd
go.mod如何在项目中使用?
grpc 降级
go get google.golang.org/grpc@v1.26.0
go mod 的使用
go mod help 查看所有的命令