Skip to content

pyroscope性能分析

背景

当服务上线后,流量增加或短暂功能故障,都会造成用户体验变差,而这时怎样才能快速找到性能瓶颈呢?这次将会介绍一套实时性能分析工具——pyroscope,让开发者可以快速定位到造成性能瓶颈的代码,而且目前还支持在 Python、Rust 或 Go 的环境。下面将主要针对 Go 环境做介绍。

什么是 Pyroscope ?

Pyroscope 是一套开源的实时性能监控平台,简单的 Agent-Server框架,让开发者可以轻松监控服务的性能,不管是要找10秒还或是多年的性能数据,都可以快速的实时呈现。由于采样分析技术,CPU 开销较低,开发者用不用在意安装此监控会不会造成任何性能上的负担。Pyroscope后台使用的存储采用Badger这套Key-Value数据库,能高效的压缩,降低的磁盘空间需求和成本。支持多种语言:Go, Python, Rust, Java 等,支持多平台,多种部署方式。假设还没有导入任何新能分析工具或或平台,那Pyroscope会是最佳的选择。

Pyroscope 框架

官方网站架构图

Pyroscope框架只分为ServerAgent而已,可以参考以上架构图,除了GO语言之外,PythonRuby都是通过pyroscope命令启动相关APP来监控系统性能的。

启动 Pyroscope Server

除了直接安装部署在本机或服务器上,还可以通过dockerk8s进行安装部署。

# MacOs
brew install pyroscope-io/brew/pyroscope
brew services start pyroscope-server

# Ubuntu/Debian
wget https://dl.pyroscope.io/release/pyroscope_"${pyroscope_version}"_amd64.deb
sudo apt-get install ./pyroscope_"${pyroscope_version}"_amd64.deb

# CentOS
wget https://dl.pyroscope.io/release/pyroscope-"${pyroscope_version}"-1-x86_64.rpm
sudo yum localinstall pyroscope-"${pyroscope_version}"-1-x86_64.rpm

# Use systemctl to enable boot start and start the service
sudo systemctl enable pyroscope-server
sudo systemctl start pyroscope-server

docker为例,安装部署方式有两种,第一种直接用docker指令部署:

docker run -it -p 4040:4040 pyroscope/pyroscope:latest server

但像这样部署的话,许多配置不能使用的,比如数据页面直接展示不需要登录,也不能限制API上报(允许某些机器通过Key来限制上报),容器销毁后监控数据会丢失。 另一种方式是通过docker-compose启动,首先配置docker-compose.yaml内容如下:

version: "3"
services:
  pyroscope:
    image: "pyroscope/pyroscope:latest"
    ports:
      - "4040:4040"
    command:
      - "server"
    environment:
      ## 限制必须使用 API 秘钥上传
      - PYROSCOPE_AUTH_INGESTION_ENABLED=true
      ## 设置账号密码登录后台
      - PYROSCOPE_AUTH_INTERNAL_ENABLED=true
    volumes:
      ## 设置数据共享目录
      - $PWD/data:/var/lib/pyroscope

配置好后,在当前目录下创建data目录保存监控数据:

mkdir data

目录结构如下:

.
├── data
└── docker-compose.yaml

1 directory, 1 file

然后输入以下命令拉起服务:

docker-compose up -d

访问http://127.0.0.1:4040进入登录页面进行验证服务是否拉起成功。

login

通过登录页面输入默认账号密码(admin:admin)进入系统后可以自行修改账号密码。

然后添加密匙(设置->API Keys),需要注意的是Role必须选择Agent才可以正常上报数据。

API Keys

在 Go 项目中使用 Agent

Go提供有两种模式,拉取(pull)模式类似Prometheus,个人更偏向推送(push)模式。

推送模式,首先在项目中添加依赖:

import "github.com/pyroscope-io/pyroscope/pkg/agent/profiler"

接着在main.go中添加Pyroscope相关上报代码即可:

package main

import (
    "github.com/pyroscope-io/pyroscope/pkg/agent/profiler"
)

func main() {
    profiler.Start(profiler.Config{
        // 项目名字, 只能英文不能中文
        ApplicationName: "go.pyroscope.example.app",
        // 按实际自己 pyroscope 服务的地址
        ServerAddress: "http://127.0.0.1:4040",
        // 如果开启了 PYROSCOPE_AUTH_INGESTION_ENABLED,
        // 按照以上步骤添加了 Key, 那么把 Key 放到此处即可
        AuthToken: "xxx", 
    })

    // your code goes here
}

最后放一张效果图:

监控效果

字段解释

字段名 含义
inuse_objects 已分配但尚未释放的对象数量
alloc_objects 已分配的对象总数(无论已释放的对象)
inuse_space 已分配但尚未释放的内存数量
alloc_space 分配的内存总量(无论已释放了多少内存)

总结

这套工具相当方便,在Go语言虽然可以使用pprof快速找到问题,但是难免还是需要手动操作的步骤才能查找出性能瓶颈。有了这套平台,就可以将全部的App都进行监控,当出现任何问题时,就可以快速通过Pyroscope查看是哪里的代码出了问题。