Golang 持续分析

Golang Pyroscope 持续分析 #

一、背景 #

分析程序性能问题时,往往需要上机器拉 pprof 并分析,过程比较繁琐。有时需要定位一个突发的负载问题,上了机器之后 负载问题就自行恢复,再想清晰定位的话恐怕需要等待下一次事发。为了能更好的分析线上偶现问题,故引入自动持续分析。恰巧持续分析这个课题已经有几个比较好的开源轮子:

方案 使用体验 开销
arca 页面有点卡,研发背景较强,稳定后可尝试 <1%
aws开源方案 社区活跃性一般,没太调研
pyroscope 功能健全,程序健壮,界面风格难以接受 2%-%5

目前调研的是pyroscope,pyroscope文献丰富部署简单,使用成本较低,计算开销也能接受。值得一提的是,pyroscope的面板可以集成进grafana,一定程度上避免生态割裂,不过操作起来似乎繁琐,接入效果并不完美,这里变没有做深入尝试,后续值得跟进。

二、实践 #

2.1安装部署 #

pyroscope部署方式多种多样,如下为容器部署Demo,可供参考。

1
2
3
4
5
6
7
8
#1.同步仓库
helm repo add pyroscope-io https://pyroscope-io.github.io/helm-chart

#2.配置存储卷:pyroscope-sc

#3.安装
helm install pyroscope pyroscope-io/pyroscope --set persistence.enabled=true \
--set persistence.storageClassName=pyroscope-sc

pyroscope本身支持鉴权,考虑到我们是纯内网环境,鉴权等相关必要配置在这里就都省略了。其他可调节配置的参数还有许多,详见 文档

2.2接入使用 #

Go版本 #

pyroscope同时支持pull和push模式,这里采用push模式。参数Tags务必受善填写,查询需要用到Tags的内容。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
func Pyroscope(srv string) func() {
	l := logrus.WithField("class", "pyroscope").WithField("hostname", hostname)

	host := "http://127.0.0.1:7777/"

	p, err := pyroscope.Start(pyroscope.Config{
		ApplicationName: fmt.Sprintf("%v.project", srv),
		ServerAddress:   host,
		Tags:            map[string]string{"hostname": hostname, "env": config.GetEnvironment().ToString()},
		ProfileTypes: []pyroscope.ProfileType{
			pyroscope.ProfileCPU,
			pyroscope.ProfileAllocObjects,
			pyroscope.ProfileAllocSpace,
			pyroscope.ProfileInuseObjects,
			pyroscope.ProfileInuseSpace,
			pyroscope.ProfileGoroutines,
			pyroscope.ProfileBlockCount,
			pyroscope.ProfileBlockDuration,
			pyroscope.ProfileMutexCount,
			pyroscope.ProfileMutexDuration,
		},
	})

	if err != nil {
		l.WithError(err).Error("failed to start pyroscope")
		return func() {}
	}

	logrus.WithField("class", "pyroscope").Info(hostname, config.IsDev())
	return func() { _ = p.Stop() }
}

Python版本 #

1
2
3
4
5
6
7
8
9
import os
import pyroscope
pyroscope.configure(
    app_name = "project"
    server_address = "http://12.7.0.01:4040",
    tags = {
        "hostname": os.getenv("HOSTNAME"),
        "env": "EnvOnline"
    }

2.3 展示效果 #

图表的数值中是选中时间的聚合数据,如果要查看具体某次的分析,框选对应的时间片即可。pyroscope本身支持Tags过滤,图示部分正在根据具体的机器名称做筛选。

2.4运维 #

如需调整监控项目,需要上pyroscope所在机器,执行相关命令:

1
2
3
4
5
#列出所有 app
pyroscope admin app get

#删除指定app
pyroscope admin app delete myapp --force

其他还有许多命令,这里不多赘述。

三、总结 #

生产使用了一个月左右,暂时没出现过问题。

性能基本上和官方的描述一致,从ECS监控来看,对服务器本身负载基本没有影响(生产曾灰度上线,做过对比)。如果对性能有极致要求,多副本项目可以酌情选择一定数量副本接入,单节点项目慎重使用。

欢迎讨论和指正。

参考: What is continuous profiling? What is Continuous Profiling? A CONTINUOUS PROFILING INFRASTRUCTURE FOR DATA CENTERS