原作者: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 年产品界面的主观评价当成今天的产品比较结论。

采集: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 分钟分辨率;更长的查询范围使用较粗的归档。
| 数据分辨率 | 归档覆盖跨度 |
|---|---|
| 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。
原文图示与结果














暂无评论内容