Golang高性能编程| 青训营笔记

148 阅读3分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的的第三篇笔记

预习 pprof使用 | golang pprof 实战

package main
import (
    // 略
    _ "net/http/pprof"  // 会自动注册 handler 到 http server,方便通过 http 接口获取程序运行采样报告
    // 略
)

func main() {
    runtime.GOMAXPROCS(1)  // 限制 CPU 使用数,避免过载
    runtime.SetMutexProfileFraction(1)  // 开启对锁调用的跟踪,每次加锁都记录
    runtime.SetBlockProfileRate(1)  // 开启对阻塞操作的跟踪,每次阻塞都会记录
    go func() {
        // 启动一个 http server,注意 pprof 相关的 handler 已经自动注册过了
        if err := http.ListenAndServe(":6060", nil); err != nil {
                log.Fatal(err)
        }
        os.Exit(0)
    }()
}

这份代码在文章中称为“炸弹”,本文实战使用pprof主要解决💣中的一下问题,CPU占用,内存占用,频繁GC,协程泄露,锁的争用,长时间阻塞。忘记内容了就去标题的超链接看吧,以下命令都有类似套路。

程序启动后在浏览器输入http://localhost:6060/debug/pprof/,会显示如下内容

之后在终端中输入的命令go tool pprof http://localhost:6060/debug/pprof/profile/xxx的xxx,都是对应的上面的allocs,goroutine,heap等等

go tool pprof http://localhost:6060/debug/pprof/heap //内存

go tool pprof http://localhost:6060/debug/pprof/allocs // GC

go tool pprof http://localhost:6060/debug/pprof/goroutine // 协程

go tool pprof http://localhost:6060/debug/pprof/mutex // 锁竞争

go tool pprof http://localhost:6060/debug/pprof/block // 阻塞

# 终端打开pprof 只记录10秒
go tool pprof -http:=8080 http://localhost:6060/debug/pprof/profile?second=10
# 查看cpu占用情况
top
# 定位函数
list xxxfunc
# 电脑中需要装有graphviz,键入web后会打开图形化分析,类似下面这样是对锁的分析
web
  • top命令的界面

  • pprof在浏览器中的图形界面

1. 性能优化建议(流批!~)

Benchmark

Slice| 两个性能陷阱

Get新知识,大内存未释放(应该和GC有关系)

字符串处理

// 方式一
s += str
// 方式二
var builder strings.Builder
builder.WriteString(str)
return builder.String()
// 方式三
buf := new (bytes.Buffer)
buf.WriteString(str)
return buf.String
  1. 使用最原始的方法每次增加时会申请新的字符串进行拷贝
  2. 使用strings.Builder和bytes.Buffer类似,他们底层的扩容机制,不需要每次拼接字符串时申请内存,而bytes.Buffer比strings.Builder略微慢一点的原因是在返回String时,bytes会多申请一次内存用来返回,String.Builder是直接取出底层指针里的内容
  3. 能不能像切片一样提前预分配好内存大小,而不用每次去扩容?确实有!~bytes.Buffer.Grow 和 strings.Builder.Grow

空结构体

实现set,将map里的value值设为空结构体类型,减少无用内存的消耗

原子操作 Atomic

2. 性能分析工具原理部分 | pprof

cpu信息的获取

heap信息的获取

Goroutine&ThreadCreate

Block&Mutex

3. 业务服务优化

建立性能评估的手段

  • 服务性能的评估方式
    • Benchmark
    • 不同负载下性能表现差异 需要用到额外的压测工具
  • 请求流量构造
    • 不同参数覆盖的逻辑不同
    • 线上真实流量
  • 压测范围
    • 单机器
    • 集群
  • 性能数据采集------>压测报告,火焰图
    • 单机
    • 集群

服务链路图

业务中可能会有问题的方面:比如使用库不规范;长时间消耗CPU干无意义重复的事情;非重要的事情被强制要求同步完成(比如高并发场景下的日志记录)