监控 Aeron®:面向你的可观测性平台的指标与告警
Aeron 在共享内存中暴露了一套丰富的无锁计数器——但它不提供 /metrics 端点。要把这些信号接入你公司的 Prometheus/Grafana/Datadog 平台,你要么写一个小 exporter(OSS),要么运行 Aeron Insights(Premium)。本页涵盖这两条路,然后把真正重要的计数器映射到它们所预示的故障模式,以及应当接入的告警条件。
Aeron 如何暴露遥测:CnC 文件
Section titled “Aeron 如何暴露遥测:CnC 文件”每个 Aeron media driver 都会在其 Aeron 目录中维护一个 command-and-control 文件 cnc.dat,以内存映射方式存在。它的各个区域中包含 counters metadata buffer、counters values buffer 和 error-log buffer。计数器就是由 driver 无锁更新的普通 64 位值;任何外部进程都可以以只读方式内存映射该文件并实时读取它们,用 Aeron 自己的话说——「对性能无显著影响」。
这就是全部的接入面。没有 push、没有 agent 协议、没有 HTTP——你映射文件并遍历。参考读取器是 AeronStat(aeron-stat 脚本),它每秒循环一次并打印所有计数器。底层它做的事和任何 exporter 完全一样:
// 规范的读取模式——用 Agrona 的 CountersReader 读取映射后的 cnc.datfinal CountersReader counters = cncFileReader.countersReader();counters.forEach((counterId, typeId, keyBuffer, label) -> { final long value = counters.getCounterValue(counterId); // → 把 {counterId, typeId, label, value} 发给你的 metrics 客户端});计数器按 type id 分组:0–99 client/driver,100–199 archive,200–299 cluster。当你把计数器转成指标时,这个 type id 就是你的路由键。
路径 1 —— OSS:自己写(或复用)一个计数器 exporter
Section titled “路径 1 —— OSS:自己写(或复用)一个计数器 exporter”Aeron OSS 没有原生的 Prometheus exporter。这是有意为之,Aeron 自己的 cookbook 也把你指向自建路线:「用 CountersReader 读取计数器数据」并喂给一个指标系统,「例如 DataDog 或 Prometheus」。模式是一个每节点 sidecar,它映射该节点的 cnc.dat,按定时遍历计数器,然后暴露 /metrics(供 Prometheus 抓取)或 push 给 StatsD/Datadog/CloudWatch。
你不必从零写起——已经有几个社区 exporter 实现了这一点:
| Exporter | 是什么 | 状态 |
|---|---|---|
singleplayer88/aeron-exporter | 通过 CncFileReader/CountersReader 读取 cnc.dat,用 Jetty 提供 /metrics。Apache-2.0。 | 近期维护(2026) |
fairtide/aeron-prometheus-stat | 同样的 CnC 读取模式,把计数器重命名为 Prometheus 惯例;附带 Docker Compose。Apache-2.0。 | 较旧(约 2023) |
scalecube/scalecube-metrics | 构建在 Agrona counters + HdrHistogram 之上的遥测库,带一个 Prometheus-over-Aeron demo。 | 活跃维护中 |
对于 Datadog、StatsD 或 CloudWatch,没有现成的集成——同样是那套 CountersReader.forEach 循环,只不过改成 push 给对应平台的客户端,而非暴露 /metrics。基于日志抓取的降级方案(解析每秒一次的 aeron-stat 控制台输出)也能用,但严格来说更差:更粗粒度、有损,而且是在重新解析你本已拥有为数值的文本。
路径 2 —— Premium:Aeron Insights
Section titled “路径 2 —— Premium:Aeron Insights”Aeron Insights(Premium,当前为 beta)是路径 1 的开箱即用版本。它提供 Prometheus exporter、一个 Grafana 示例仪表盘,以及一个 CLI。这些 exporter「通过读取 Aeron 创建的文件——主要是 CnC 文件」——外加 archive/cluster mark 文件来采集数据,也就是同一套只读方法,只是被打包并受支持——提供两种每节点交付模式:
- HTTP-server exporter(默认
:8080,localhost)—— Prometheus 直接抓取每个节点。这是常见做法。 - Push-client exporter —— 按间隔(默认 1s)推送给一个 Prometheus Push Gateway。
回报是:Insights 开箱即发出有名字、有文档的 Prometheus 指标(cluster_*、driver_*、archive_*),并带一个 Grafana「Cluster Overview」仪表盘,而不是一堆你得自己命名和维护的、只带 type id 的原始计数器。
| OSS 自建 exporter | Premium Aeron Insights | |
|---|---|---|
| 读取 | cnc.dat(靠你的代码) | cnc.dat + mark 文件(已打包) |
| 指标命名 | 你自己定义 | 有文档的 cluster_* / driver_* / archive_* |
| Grafana 仪表盘 | 你自己搭 | 附带「Cluster Overview」示例 |
| 交付方式 | 你写什么就是什么 | HTTP 抓取或 Push Gateway |
| 支持 | 社区 / 自己 | Adaptive(beta) |
| 成本 | 免费(Apache-2.0) | 订阅 |
真正重要的计数器(以及「坏」长什么样)
Section titled “真正重要的计数器(以及「坏」长什么样)”你不需要把 Aeron 的所有计数器都放上仪表盘。对一个集群化的撮合引擎来说,下面这些是承重的。OSS 列是 CnC 文件里的计数器标签 / type id;Insights 列是对应的 Prometheus 指标名(若存在)。
| 信号 | OSS 计数器 (type id) | Insights 指标 | 如何解读 |
|---|---|---|---|
| Commit position | Cluster commit-pos: (203) | cluster_commit_position_total | 集群的心跳——被 quorum 复制到的 log 位置 |
| Append position | log recording 的 archive rec-pos | (无专门指标) | leader 已追加到哪里;与 commit 的差距 = follower 滞后 |
| 节点角色 | Cluster node role (201) | cluster_node_role | 2 = Leader,0 = Follower,1 = Candidate |
| 共识状态 | Consensus Module state (200) | cluster_consensus_module_state | 1 = Active,3 = 正在打快照 |
| 选举状态 / 计数 | Cluster election state (207) / election count (238) | cluster_election_state | 稳态 = 17(Closed);计数不应上升 |
| CM 周期时间 | Cluster max cycle time in ns (216) / exceeded (217) | cluster_max_cycle_time_seconds | consensus module 的 duty-cycle 延迟 |
| Service 周期时间 | Cluster container max cycle time in ns (218) / exceeded (219) | (带 service 标签的 cycle 指标) | 你的服务代码的 duty-cycle 延迟 |
| 错误 | Cluster Errors (212) / Cluster Container Errors (215) | cluster_errors_total | 单调累计——任何增量都值得一看 |
| 有效快照 | Cluster snapshot count (205) | cluster_valid_snapshots | 可用快照的数量 |
| 快照年龄 | (由 recording-log 时间戳推算) | cluster_last_snapshot_timestamp_seconds | 旧快照 ⇒ 恢复时回放漫长 |
| 快照时长 | Total max snapshot duration in ns (234) / exceeded (235) | cluster_snapshot_duration_threshold_exceeded_total | 长快照会拖住热路径(OSS) |
| 背压 | snd-bpe (13) / Sender flow control limits | driver_sender_bpe_total | 「健康系统中应为零」 |
| 丢包 / NAK | NAKs sent/received、Retransmits sent(type 0) | driver_nak_messages_*_total、driver_retransmits_sent_total | 网络丢包 ⇒ 复制被拖慢 |
| 存活性 | (计数器更新的新鲜度) | cluster_activity_age_seconds、driver_heartbeat_age_seconds | 距该组件上次活跃过去了多少秒 |
告警:把指标映射到故障模式
Section titled “告警:把指标映射到故障模式”下面每一项都把一个指标绑定到某个故障模式运维手册场景。Aeron 几乎不发布任何数值阈值——下表中的计时器是有文档的;其余都属于运维判断,因此要对照你自己的基线来校准,并从宽松阈值起步以避免告警疲劳。
| 告警 | 条件 | 依据 / 文档来源 |
|---|---|---|
| Commit 停滞(严重) | 状态为 Active 时 commit-pos 增量 == 0 持续 > 约 10s | Aeron 自己的「No catchup progress」警告会在 commit 停止推进、超过 **leader 心跳超时(默认 10s)**时触发。成因:应用代码慢、机器负载、GC。 |
| 无 leader(严重) | 超过选举超时仍无节点报告角色 == Leader (2) | 选举进行中 = 集群没在提交。 |
| 选举频繁(高) | election count (238) 在上升,或 election state 不回到 17(Closed) | 每一次自增都是一次 p99 悬崖。触发条件:心跳超时、丢失 quorum。(「Election storm」不是文档术语——自己定速率。) |
| Follower 滞后(中) | rec-pos(log) − commit-pos 随时间增长 | leader 追加的速度快于 quorum 确认——正走向背压或 quorum 丢失。无文档化的差距阈值。 |
| 周期时间超限(中) | cycle time exceeded 计数器(217/219)在自增 | CM 与 service 的 duty-cycle 阈值默认为 100ms。尖刺 = GC / CPU 饥饿;一次 10ms 的周期就是 p99 上一个 10ms 的坑。 |
| 错误上升(高) | Cluster Errors (212) 增量 > 0 | 然后通过 ClusterTool errors 读文本。无文档化的数值速率。 |
| 快照过旧(中) | 当前时间 − cluster_last_snapshot_timestamp_seconds > 你的恢复预算 | Aeron 中快照是手动的——旧快照意味着重启时漫长的 log 回放。见快照失败与恢复。 |
| 快照过慢(低/中) | 快照时长 exceeded (235) 在自增 | 阈值默认 1s。在 OSS 中快照会拖住热路径;在 leader 上则会落在最大延迟上。 |
| 背压 / 丢包(中) | snd-bpe、NAK 或重传速率高于基线 | subscriber/follower 跟不上,或网络丢包拖慢复制。无文档化的速率阈值。 |
| 存储耗尽(严重) | archive/cluster 卷的可用空间低于你的下限 | archive 存储耗尽会抛 ClusterTerminationException 并终止节点——这是唯一一种总是终止性的快照/archive 故障。要在它发生之前告警。 |
| 节点失联(严重) | cluster_activity_age_seconds / driver_heartbeat_age_seconds 在上升,或抓取目标掉线 | 该组件停止更新计数器——进程已死或卡死。 |
仪表盘上到底该放什么
Section titled “仪表盘上到底该放什么”如果你只搭一组面板,就照这个来——从上到下按你排障的顺序排列:
- 它还活着吗? 每个节点的角色(恰好一个 Leader)、存活/心跳年龄、抓取目标是否在线。
- 它在推进吗? commit-position 速率(你真正的吞吐量)以及 append−commit 差距。
- 它稳定吗? 选举计数(一条平线 = 健康)以及 consensus-module 状态。
- 瓶颈是你的代码吗? service 周期时间 vs. consensus 周期时间——若 service ≫ consensus,问题在你的 handler,而非 Raft。
- 底层健康吗? 背压、NAK/重传速率、archive/磁盘可用空间。
- 你能快速恢复吗? 快照年龄、有效快照数、快照时长超限。
- 计数器模型:
CncFileDescriptor、 AgronaCountersReader、AeronStat、 以及 Monitoring and Debugging wiki (「可被任何外部进程读取,对性能无显著影响」)。 - 计数器名称/type id:
AeronCounters.java、SystemCounterDescriptor.java、ConsensusModule.java(标签 + 默认值:10s 心跳、100ms 周期、1s 快照),以及 Understanding Cluster Counters / The Aeron Files — Counters(append position = archiverec-pos)。 - 自建 exporter 指导:Aeron cookbook — Read counters (点名 Datadog + Prometheus)。社区 exporter: singleplayer88/aeron-exporter、 fairtide/aeron-prometheus-stat、 scalecube/scalecube-metrics。
- 告警依据:Cluster errors(「No catchup
progress」;存储耗尽 →
ClusterTerminationException)、 Cluster troubleshooting。 - Premium:Aeron Insights 概览
(beta;三个组件)、Prometheus exporters
(读取 CnC 文件;HTTP-server vs push-client)、Aeron metrics
(逐字的
cluster_*/driver_*指标名与描述)。
本站与 Adaptive Financial Consulting Limited 或 Aeron 项目无任何关联,未获其背书或赞助。 Aeron 是 Adaptive Financial Consulting Limited 的注册商标。
Aeron 是 Adaptive Financial Consulting Limited 在英国及其他国家/地区的商标。