golang bug_fix

· 1392 words · 3 minute read

可以解决的问题 🔗

遇到过的 bug

  • golang 中数组和切片的区别,数组是值类型,函数传参数时是拷贝一个副本。
  • init() 函数滥用
  • 函数功能是查询类的,能不用指针传参数就不用,避免函数内部对 对象做修改
  • 代码里不要吞掉任何一个错误
  • first path segment in URL cannot contain colon 原因:字符串 http 前面多了空格,post 请求在本地就会失败
  • err:crypto/cipher: input not full blocks
    • AES 加密后的数据存入 mysql 时,由于字段有长度限制, 加密后的内容被截断了,所以 AES 解密时爆出这个 panic
  • 问题排查 http
    • 499 对应的是 “client has closed connection”。这很有可能是因为服务器端处理的时间过长,客户端主动关闭
    • 字段总结 remote_addr, x_forwarded_for
  • kafka: the provided member is not known in the current generation kafka
    • rebalance
  • signal.Notify(signals) (Notify 使用时需要指定接收信号的类型), 这种写法 <-signals 可以接收 os 发的 64 种信号, 其中 broken pipe signal 导致进程主进程结束
    • 本质是 IOError 错误, 读写文件 IO 和网络 Socket IO
  • 管道存在上游发送数据的进程,下游读取数据的进程,在下游不再需要读取上游数据的时候,就会发送 SIGPIPE 信号给上游进程
    • Broken Pipe 是可以忽略
  • .ignore 文件中配置 dubug,导致忽略了 vendor 里的 dubug 包,导致本地编译通过,但是远程 scm 编译失败
  • brew upgrade go && should modify .zshrc
  • ss -l 看到主机上的端口在使用, lsof -i:port 没有发现使用这个端口的进程
  • Unix domain socket 同一台操作系统上的两个或多个进程进行数据通信 跨进程通信
  • 使用 循环迭代器变量的引用, 大概率全部遍历的都是迭代的最后一个元素
  • es 使用上坑很多
    • script 方式更新文档时,字符串需要额外添加`"'" +str + "'"``
    • 不指定返回条数,默认只会回 10 条

未解决的问题 🔗

  • 构建 go module 项目时,go get github.com/xxx 后,在 nvim 中 出现 no required module privides package xxx
    • 但是可以 go run 起来,之后换成 go get -u github.com/xxx 之后,重启 nvim 就没有出现这个问题了, 所以问题是哪儿,在这里 mark 一下。

gopls 插件占用内存过大, 不能忍受。

unsolved: 阅读go源码时,执行单测出现: use of internal package internal/byteal not allowed
cannot solve
Failed to run "go env env,-json,GOMOD": Command failed: /usr/local/go/bin/go env -json GOMOD $GOPATH/go.mod exists but should not
2022-09-12 晚。

在 golang 源码里点击跳转到定义,却是跳转到 golang 安装目录下的源代码,而不是本项目原有的文件夹下
怎样在 vs code 下阅读 golang 的源代码?
https://stackoverflow.com/questions/58018729/go-linter-in-vs-code-not-working-for-packages-across-multiple-files

could not import fmt (cannot find package "fmt" in any of
	/usr/local/go/src/fmt (from $GOROOT)
	/Users/brett/go/src/fmt (from $GOPATH))compilerBrokenImport
$ code $GOROOT
No package found for open file, go/src/cmd/compile/main.go

容器中运行 go 程序 🔗

runtime/cgo: pthread_create failed: Operation not permitted #467 🔗

docker run --privileged

单测 🔗

单测 mock 框架,测试框架 stub/mock

官方测试工具 gomock 🔗

install: go get github.com/golang/mock/gomock, github.com/golang/mock/mockgen.

工具 🔗

  • Guru 导航 go 代码的编辑器集成工具
    • 变量,函数的声明地点
    • 变量,函数的所有引用地点
    • 实现此接口的所有具体类型
  • golang.org/x/tools/cmd/guru

go monkey 🔗

package main
func from() int {return 1}
func to() int (return 2)
func main() {
  // 在执行from之前把from函数内的机器码 替换为一条跳转指令,让cpu跳转到to函数的机器码上执行。
  patch(from, to)
  fmt.Println(from()) // should print 2
}

taoshu.in/go/monkey

  • 找到 from, to 的内存地址
  • 修改 from 函数的机器码,构造跳转指令,跳到 to 的内存地址上

调试 🔗

  • delve 调试工具
  • gdb 单步调试 go 程序的执行过程 Delve 更好
  • 执行某个单测函数 go test -run TestDefine ./compiler

性能分析 🔗

利用 runtime/pprof, net/http/pprof 采集运行时数据

  • pprof (CPU profiles, Heap profiles, block profile, traces)

    • kite, ginex 框架开启了 prof 功能
    • 定时任务,消费者等 worker 需要 import _ net/http/pprof 手动开启
    • 性能 pprof
      • go tool pprof http://localhost:8080/debug/pprof/profile
      • http://127.0.0.1:8080/debug/pprof/heap?debug=1
      • 终端连接到 go tool pprof -inuse_space http://127.0.0.1:8080/debug/pprof/heap
      • svg go tool pprof -alloc_space -cum -svg http://127.0.0.1:8080/debug/pprof/heap > heap.svg
  • wrk 压力测试 github.com/juju/ratelimit

  • 优化 go 程序 运行速度的方向 只对关键的路径进行优化 (优化运行速度,开会速度会慢 hah)

  1. 避免堆分配可以成为优化的主要方向。 若频繁使用堆,可以 sync.Pool 复用对象
  2. cpu cache line(64 字节),结构体填充,避免 False Sharing。
  3. 为了保证 cache 的一致性,对内存的一个小小的写入都会让 cache line 被淘汰。
  4. 对相邻地址的读操作就无法命中对应的 cache line。

go fuzzing 🔗