Ruby 应用接入 Pyroscope 持续性能剖析:simple 示例从零到火焰图
2026/9/15 14:43:44 网站建设 项目流程

Ruby 应用接入 Pyroscope 持续性能剖析:simple 示例从零到火焰图

【免费下载链接】pyroscopeContinuous Profiling Platform. Debug performance issues down to a single line of code项目地址: https://gitcode.com/GitHub_Trending/py/pyroscope

Pyroscope 是一个持续性能剖析平台(Continuous Profiling Platform),可把性能问题定位到一行代码。本指南以仓库中的examples/language-sdk-instrumentation/ruby/simple示例为蓝本,完整讲解如何用官方 Ruby SDK(pyroscopegem)为 Ruby 应用接入 Pyroscope:包括环境搭建、SDK 配置、静态与动态标签(tag)注入,以及如何在 Grafana 中查看火焰图。读完本文,你将能够在本地一键跑起一个可观测的 Ruby 剖析示例,并理解其背后的数据通路。

一、示例概览:一个最小可运行的 Ruby 剖析项目

simple示例是整个 Ruby 示例家族中最小的一个,它的目录结构如下:

examples/language-sdk-instrumentation/ruby/simple/ ├── Dockerfile # 应用镜像:Ruby 3.3.9 + pyroscope gem ├── Gemfile # 声明 pyroscope gem 版本 ├── Gemfile.lock # 锁定的依赖(含各平台二进制) ├── main.rb # 被剖析的 Ruby 应用本体 ├── docker-compose.yml # pyroscope + app + grafana 三服务编排 ├── grafana-provisioning/ │ └── datasources/ │ └── pyroscope.yml # Grafana 数据源自动配置 └── README.md # 本示例的启动说明

与同目录下的rideshare(模拟网约车公司多服务、多区域场景)和rideshare_rails(Rails 版本)相比,simple只保留了一个死循环 CPU 负载程序main.rb,用于演示最基础的接入与打标签方式,适合作为学习 Pyroscope Ruby SDK 的起点。

二、快速启动:三条命令跑起完整链路

根据 simple/README.md 的说明,启动示例共分两步:

# 1. 拉取最新的 pyroscope 与 grafana 镜像: docker pull grafana/pyroscope:latest docker pull grafana/grafana:latest # 2. 构建并启动示例项目: docker compose up --build # 3. 如需重置数据库(重新开始收集数据): docker compose down

启动后,docker compose up --build会依次拉起三个服务(见 simple/docker-compose.yml):

  • pyroscope:Pyroscope 服务端,暴露4040:4040端口,负责接收剖析数据并提供查询 API;
  • app:通过build: .基于本地 Dockerfile 构建的 Ruby 应用,持续产生 CPU 负载并上报剖析数据;
  • grafana:Grafana 前端,暴露3000:3000,已预装 Pyroscope App 插件。

注意:simple/docker-compose.ymlgrafana-provisioning/datasources/pyroscope.yml均由仓库模板生成(文件头注释标明来源为examples/_templates/下的模板,通过make examples/sync-templates同步),如需修改需改模板而非直接编辑生成文件。

在 Grafana 中查看火焰图

服务全部就绪后,浏览器打开以下链接即可直接进入火焰图探索页面:

http://localhost:3000/a/grafana-pyroscope-app/explore?explorationType=flame-graph&var-serviceName=test.ruby.app&var-profileMetricId=process_cpu:cpu:nanoseconds:cpu:nanoseconds

该链接预置了两个关键查询参数:

  • var-serviceName=test.ruby.app:对应main.rbconfig.application_name设置的"test.ruby.app"
  • var-profileMetricId=process_cpu:cpu:nanoseconds:cpu:nanoseconds:选择process_cpu这一 CPU 采样指标(nanoseconds 计量单位)。

由于 Grafana 容器开启了匿名登录(GF_AUTH_ANONYMOUS_ENABLED=true且禁用登录表单),打开即用,无需账号。

三、被剖析的应用本体:main.rb 源码逐行解读

simple/main.rb 完整展示了 Pyroscope Ruby SDK 的两种核心用法:初始化配置与动态打标签。

3.1 SDK 初始化配置

require "pyroscope" Pyroscope.configure do |config| config.application_name = "test.ruby.app" config.server_address = "http://pyroscope:4040/" config.tags = { :region => "us-east", :hostname => ENV["HOSTNAME"] } end

四个配置项的含义:

配置项取值示例说明
application_name"test.ruby.app"应用名,在 Grafana 中作为服务标识(service name),对应火焰图查询参数var-serviceName
server_address"http://pyroscope:4040/"Pyroscope 服务端地址;在 Docker Compose 网络内直接使用服务名pyroscope,宿主机访问则用localhost:4040
tags(静态标签)region: "us-east"hostname: ENV["HOSTNAME"]在初始化阶段固定的标签,如地域、主机名;这里 hostname 取自容器环境变量,可动态注入
config.tags的键Ruby Symbol / String 均可示例同时展示了:regionSymbol 键与"function"字符串键两种写法

3.2 静态标签与动态标签

main.rb演示了 Pyroscope 最核心的能力——标签(tag):

  • 静态标签:在Pyroscope.configureconfig.tags中声明,生命周期与应用相同,适合标注地域、环境、主机等相对固定的维度;
  • 动态标签:在函数内部用Pyroscope.tag_wrapper包裹,随代码块进入/退出而生效/失效。

3.3 用 tag_wrapper 动态区分热点函数

def fast_function Pyroscope.tag_wrapper({ "function" => "fast" }) do work(20000) end end def slow_function Pyroscope.tag_wrapper({ "function" => "slow" }) do work(80000) end end

tag_wrapper的行为(可对照 ruby/README.md 中的find_nearest_vehicle示例理解):

  1. 进入代码块前,向当前剖析上下文追加标签{ "function" => "fast" }(或"slow");
  2. 执行代码块内的业务逻辑(这里是work(n)死循环 CPU 消耗);
  3. 代码块结束,SDK 在幕后自动移除该标签,避免污染后续调用。

主循环则交替调用快慢函数,制造两个耗时差异明显的热点:

while true fast_function # work(20000),CPU 消耗较低 slow_function # work(80000),CPU 消耗约为 fast 的 4 倍 end

这样在火焰图中就能直观看到work在不同标签下的 CPU 占比差异,这正是 tag 在性能对比中的典型用法:把同一函数的不同调用路径(如不同端点、不同业务分支)拆开对比。

四、Dockerfile 与依赖:SDK 版本与运行环境

simple/Dockerfile 揭示了示例的运行环境细节:

FROM ruby:3.3.9 WORKDIR /usr/src/app RUN adduser --disabled-password --gecos --quiet pyroscope USER pyroscope COPY --from=pyroscope/pyroscope:latest /usr/bin/pyroscope /usr/bin/pyroscope COPY --chown=pyroscope main.rb ./main.rb COPY --chown=pyroscope Gemfile ./Gemfile COPY --chown=pyroscope Gemfile.lock ./Gemfile.lock ENV PYROSCOPE_APPLICATION_NAME=simple.ruby.app ENV PYROSCOPE_SERVER_ADDRESS=http://pyroscope:4040/ ENV PYROSCOPE_LOG_LEVEL=debug RUN bundle install CMD ["ruby", "main.rb"]

几个值得注意的点:

  • 基础镜像ruby:3.3.9,以非 root 用户pyroscope运行;
  • 通过COPY --from=pyroscope/pyroscope:latest从 Pyroscope 官方镜像中拷入 CLI 二进制(示例未直接调用,但保留了这一能力);
  • 设置了三个环境变量:PYROSCOPE_APPLICATION_NAMEPYROSCOPE_SERVER_ADDRESSPYROSCOPE_LOG_LEVEL=debug(后两者会被main.rb中的显式配置覆盖或补充,其中日志级别有助于排查上报问题);
  • CMD ["ruby", "main.rb"]启动主程序。

依赖声明见 simple/Gemfile:gem 'pyroscope', '= 1.0.7',版本被精确锁定。由 Gemfile.lock 可见,pyroscopegem 通过ffi依赖绑定各平台原生二进制(aarch64-linuxarm64-darwinx86_64-linux等),即该 gem 在安装时会拉取对应平台的剖析采集器,这也是它能做到轻量采集的底层机制。

五、Grafana 数据源自动配置

Grafana 容器通过挂载卷./grafana-provisioning:/etc/grafana/provisioning实现开箱即用的数据源配置,核心文件为 simple/grafana-provisioning/datasources/pyroscope.yml:

apiVersion: 1 datasources: - uid: pyroscope type: grafana-pyroscope-datasource name: Pyroscope url: http://pyroscope:4040 jsonData: keepCookies: [pyroscope_git_session] ## 若配合 Grafana Cloud 使用,可取消注释: # basicAuth: true # basicAuthUser: '123456' # secureJsonData: # basicAuthPassword: PASSWORD

要点:

  • 数据源类型为grafana-pyroscope-datasource,指向容器网络内的http://pyroscope:4040
  • 文件中的注释给出了接入 Grafana Cloud 时的基本认证(basicAuth)配置范式;
  • 该文件同样由模板生成(来源为examples/_templates/下的 grafana 模板)。

而在 simple/docker-compose.yml 中,Grafana 服务还通过环境变量预装插件、开启匿名访问并启用与链路相关的功能开关:

GF_PLUGINS_PREINSTALL_SYNC=grafana-pyroscope-app GF_AUTH_ANONYMOUS_ENABLED=true GF_AUTH_ANONYMOUS_ORG_ROLE=Admin GF_AUTH_DISABLE_LOGIN_FORM=true GF_FEATURE_TOGGLES_ENABLE=traceToProfiles tracesEmbeddedFlameGraph

六、从 simple 出发:标签能力与进阶示例

simple只展示了function这一个动态标签。标签能力在更大的示例中体现得更充分:同目录的 ruby/README.md 记录了 rideshare 示例的做法——用静态标签标注服务器所在region,用Pyroscope.tag_wrapper动态标注端点(vehicle),从而在火焰图中按维度切分数据,定位"到底是哪个端点慢、还是哪个区域慢"。

仓库中还提供了两个进阶示例,可直接对照学习:

  • rideshare:模拟三个区域、三个端点的网约车服务,并附带load-generator.py制造压测流量,火焰图中可直接观察不同函数 CPU 占比与标签过滤效果;
  • rideshare_rails:同一场景的 Rails(含application_controller.rbbike_controller.rb等)实现,其 config/initializers/pyroscope.rb 展示了在 Rails 初始化器中接入 SDK 的方式,更贴近真实生产项目。

七、常见问题与排查思路

  • 火焰图迟迟不更新:Pyroscope 按采样间隔聚合数据,一般等待 20~30 秒后刷新页面即可看到(该节奏在 ruby/README.md 中有说明);
  • 看不到test.ruby.app服务:确认main.rbapplication_name与 Grafana 链接中的var-serviceName一致,且容器日志中无上报错误(Dockerfile 中设置了PYROSCOPE_LOG_LEVEL=debug,可用docker compose logs app查看);
  • 需要清空数据重来:执行docker compose down后重新docker compose up --build即可(示例未挂载持久化卷,容器销毁即数据重置);
  • 服务地址不通:容器内互访必须使用 Compose 服务名pyroscope:4040,宿主机或外部访问才使用localhost:4040

至此,你已经掌握了一条完整的 Ruby 持续剖析链路:main.rb采集 CPU 采样并通过 gem 上报到pyroscope:4040,Grafana 通过预置数据源读取并渲染为火焰图,而标签机制则让你能够按任意业务维度(区域、端点、函数分支)拆解性能数据,快速定位性能瓶颈。

【免费下载链接】pyroscopeContinuous Profiling Platform. Debug performance issues down to a single line of code项目地址: https://gitcode.com/GitHub_Trending/py/pyroscope

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询