collectd + Graphite + Grafana 搭建网络质量监控系统

原作者:Zhuoyun Wei(wzyboy),原文发表于 2016 年 3 月 21 日,见 wzyboy’s blog。本文依据完整原文整理,保留采集、存储、查询与展示链路,并补充版本和安全说明。原作采用 CC BY-NC-SA 4.0;本整理稿保留署名、来源及该许可声明。

版本背景:这是一份 2016 年的家庭服务器实践记录。原文里的 Python 2 安装命令、第三方 Graphite-API、旧 Grafana 面板与登录方式只说明当时的环境,不是当前安装指南。本文没有安装组件、启动服务或发出 ICMP 探测,代码和配置仅作静态核验。

让采集、存储和展示各自完成一件事

作者购入 Gen8 服务器后,除网络存储之外,还借助 ESXi 运行其他服务。网络质量监控是其中一项用途。与把所有功能集中在一个工具里相比,这套方案选择 collectd 采集指标,Graphite 相关组件接收和保存时间序列,Grafana 负责查询展示。

原文提到 SmokePing 作为常见的网络质量监控工具,并解释自己选择了更灵活的组合。这里保留作者的选型背景,不把对 2016 年产品界面的主观评价当成今天的产品比较结论。

网络质量监控链路:获准探测目标的 ICMP 数据由 collectd ping 采集,经 write_graphite 发送到 Carbon,存入 Whisper;Graphite-API 同时查询磁盘和 Carbon 缓存,Grafana 请求 API 绘制图表。
未完纪根据原文自绘架构图。端口是原文示例配置,不表示这些服务已部署或对外开放。

采集:collectd 的 ping 与 write_graphite 插件

collectd 是持续收集系统指标的进程,自带多种插件,也支持扩展插件和数据类型。原文的网络质量指标使用 ping 插件,它依赖 Liboping。按系统提供的包方式安装相关组件后,再编辑 collectd 的配置;原文路径是 /etc/collectd.conf,实际发行版可能有所不同。

以下保留原文配置以便逐项理解。里面的公网地址是原文探测目标,执行时应改成你获得明确探测许可的目标并控制频率,不能把示例地址视作探测授权。

Hostname "your-hostname"
FQDNLookup false

LoadPlugin ping
LoadPlugin write_graphite

<Plugin ping>
  Host "8.8.8.8"
  Host "8.8.4.4"
  Interval 1.0
  Timeout 0.9
</Plugin>

<Plugin write_graphite>
  <Node "localhost">
    Host "localhost"
    Port "2003"
    Protocol "tcp"
    LogSendErrors true
  </Node>
</Plugin>

Hostname 决定上报使用的主机名,FQDNLookup false 关闭完全限定域名查询。两个 LoadPlugin 分别加载探测与输出插件。

在 ping 配置中,每行 Host 添加一个目标;Interval 1.0 表示每秒探测一次;Timeout 0.9 表示等待回包的超时。原文还提到 SourceAddress、Device,可在有需要时指定发包源地址或设备。

最容易混淆的是两个时间尺度:ping 插件内部的 Interval 是探测周期,不是指标上报周期。上报仍遵循 collectd 的全局周期,原文默认值是 10 秒;一次上报中的 RTT 是这个上报区间里观测到的往返时延的算术平均值。把采样频率调高,并不会自动让存储获得相同粒度的每个样本。

write_graphite 中填写 Carbon 接收端的地址、端口和协议。原文将 collectd 与 carbon-cache.py 放在同一台机器,所以使用 localhost:2003;若采集器运行在路由器,Carbon 运行在另一台设备,就需要使用对端的受控内部地址。

Graphite 的明文数据行形如:

foo.bar.baz 123 1458372405

三段依次是指标路径、数值和时间戳,以空格分隔。这个例子是格式说明,不是新采集结果。配置中的普通 TCP 并不自带身份验证或加密;跨主机传输应限制在可信网络,或采用经审核的加密通道,并限制谁能写入指标。指标名也应来自受控采集器,不应让任意用户输入直接组成协议行。

原文此时暂不启动 collectd,因为 Carbon 尚未运行。先准备接收、存储和查询环节,再启动采集,可以避免一开始就持续出现发送失败。

接收与保存:Carbon 和 Whisper

Graphite 由几个职责不同的组件组成。Carbon(包括 carbon-cache.py、carbon-relay.py 等)接收数据点;Whisper 是磁盘上的时间序列存储格式;Graphite Web 是基于 Django 的网页应用,同时提供查询 API 与页面。

作者这次没有使用 Graphite Web 的展示页面,而是选择第三方 Graphite-API 提供查询接口,再让 Grafana 画图。原文记载当时通过 pip2 install carbon 安装 Carbon。这属于历史命令,本文不建议据此建立新的 Python 2 环境,也不声称当前 Carbon 仍只支持 Python 2。实际部署应选择受支持、已核对版本的发行版包或官方安装路径。

Whisper 文件预分配存储空间,单个文件的容量由保留策略决定。近期数据可以保存得更细,较远的数据用较粗粒度保留,超出期限的旧数据会被覆盖。原文的 storage-schemas.conf 示例为:

[ping]
pattern = \.ping\.
retentions = 10s:1d,1m:30d,5m:180d,30m:1y

[default]
pattern = .*
retentions = 1m:1d,5m:30d,30m:180d,1h:1y

pattern 匹配指标名,retentions 为各级归档定义“分辨率:保留跨度”。ping 指标在一天范围内保留 10 秒分辨率,其余指标在一天范围内保留 1 分钟分辨率;更长的查询范围使用较粗的归档。

原文 ping 策略的分辨率与覆盖跨度
数据分辨率 归档覆盖跨度
10 秒 1 天
1 分钟 30 天
5 分钟 180 天
30 分钟 1 年

编辑澄清:这里的 30 天、180 天和 1 年是各级归档各自覆盖的时间跨度,不能把它们相加成总保存时长。降采样也不会恢复原来没有记录的短时尖峰;上报平均、存储归档和查询聚合会影响你能看到的细节。

这些 schema 只在创建新的 .wsp 文件时决定它的布局。修改配置并不会自动改写已有文件。原文提到可通过 whisper-resize.py 调整已有文件,但这种操作涉及重写历史数据,应先备份、在副本中验证,并确认所用版本与预期聚合行为。本稿没有执行调整命令,也不提供一键批量重写示例。

查询:让 Graphite-API 同时看到磁盘与缓存

作者在原环境中通过系统安装包部署 Graphite-API,指出它包含非 Python 图形库依赖,直接编译安装可能更麻烦。Ubuntu、Debian 和 Arch Linux 的包名与仓库记录属于原文当年的环境信息,不能保证目前仍可直接使用。

配置文件 graphite-api.yaml 的核心是 Whisper 文件目录与 Carbon 缓存查询。具体目录取决于安装方式,必须与 Carbon 真正写入的位置一致:

finders:
  - graphite_api.finders.whisper.WhisperFinder
whisper:
  directories:
    - /var/lib/carbon/whisper
carbon:
  hosts:
    - 127.0.0.1:7002
  timeout: 1
  retry_delay: 15
  carbon_prefix: carbon
  replication_factor: 1

WhisperFinder 查找磁盘上的 Whisper 数据;whisper.directories 给出根目录。Carbon 接收数据之后可能先把点缓存在内存里,尚未来得及写盘,所以原文还配置了 carbonlink,从 127.0.0.1:7002 查询这部分缓存。

要分清 2003 和 7002:前者是原例 collectd 写入指标的入口,后者是查询 Carbon 缓存的接口。这个 YAML 的 carbon 节不是给 collectd 发数据用的。两者都应限制访问来源,不能因最终只在 Grafana 看图,就把底层服务无条件暴露到公网。

配置完成后,原文先启动 Carbon 与 Graphite-API,再启动 collectd。排查时可依次确认采集器是否成功发送、Carbon 是否写入对应指标文件、API 是否读到正确目录与缓存。本文仅给出排查顺序,没有伪造服务状态或查询返回值。

展示:Grafana 连接 Graphite 数据源

Grafana 把查询结果绘制为图表。原文使用当时的二进制包部署,并在 :3000 访问 Web 界面;通过添加 Graphite 数据源,把 Graphite-API 的地址和原文默认端口 8888 填入数据源设置,再选择指标和 Graphite 函数组装面板。

原文提到初始凭据 admin / admin 和在 grafana.ini 开启匿名登录。它们仅作为旧文行为记录保留,不能原样用于对外环境。应在对外提供服务前完成管理凭据变更、身份验证与访问控制,并按最小权限配置数据源和匿名访问;本稿没有复用或设置任何口令。

作者展示的历史看板使用 Templating、Singlestat Panel 等当时的功能名称。本文不提供伪造的新版界面截图,也不宣称这些面板名字在当前版本仍保持不变。原图中一段 100% 丢包,作者解释为某台 VPS 所在机房出现了问题;这只是作者当时的观察,没有在本文中进行独立探测或因果验证。

解释网络质量数据时的边界

编辑补充:ICMP 的 RTT 与丢包可以揭示一条观察路径上的变化,却不能直接证明应用服务是否可用。目标可能限制 ICMP,路径和业务流量也可能受到不同处理;仪表盘没有数据还可能是采集器停了、写入失败或查询目录错误,而不是网络突然完全正常或完全中断。

在设计面板时,应标清 RTT 单位、丢包指标的单位与取值范围,并区分“没有样本”和“采样结果为零”。不要在未经确认的情况下把某个 0 到 1 的比值直接当作 0 到 100 的百分数。原文没有给出完整仪表盘导出,本稿因此不补造面板查询或 JSON。

把同一链路扩展到更多指标

作者后来用 collectd 继续监控局域网中的笔记本、Gen8 上的虚拟机及 Raspberry Pi,采集 CPU、内存、磁盘和网络指标。采集内容改变后,仍可沿用接收、存储、查询和展示这条链,但应为不同指标选择合适的采样与保留策略。

原文还提到 Windows 上协议兼容的 SSC Serv,以及当时免费版本五分钟一次的上报限制。这属于历史产品记录,本文不将它当作现在仍有效的价格或功能承诺。更换采集器时,首先应核对协议、指标类型、时间戳和命名规则是否一致。

这篇实践留下的长期价值,是把监控系统拆成可独立观察的几个环节:谁采样、谁接收、谁保存、谁查询、谁展示。出现缺口或异常时,沿着这条链逐段核对,比只盯着最终一张图更容易定位原因。

来源、许可与改动

来源:Zhuoyun Wei(wzyboy):collectd + Graphite + Grafana 搭建网络质量监控系统,2016-03-21;版权署名为 © 2009–2026 Zhuoyun Wei,站点内容许可为 CC BY-NC-SA 4.0。本文注明作者并链接原作;按同一许可保留整理稿声明。

整理改动:改为第三人称叙述,保留所有关键配置;对 Python 2、旧面板、默认口令、匿名访问、网络探测和 Whisper 历史数据调整作明确标注;澄清保留跨度不可相加;补充原创架构图并保留原文历史截图。未声称修复或验证了整个软件栈。核验日期:2026-10-05。

原文图示与结果

原文 collectd、Carbon、Whisper、Graphite-API 与 Grafana 架构
原文 collectd、Carbon、Whisper、Graphite-API 与 Grafana 架构。原图:Zhuoyun Wei(wzyboy),CC BY-NC-SA 4.0。 原图来源。历史原作内容,非本文重新执行所得。
原作者 2016 年的 Grafana 网络质量看板,含 RTT、丢包和标准差
原作者 2016 年的 Grafana 网络质量看板,含 RTT、丢包和标准差。原图:Zhuoyun Wei(wzyboy),CC BY-NC-SA 4.0。 原图来源。历史原作内容,非本文重新执行所得。
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容