监控 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) / Cluster election count (238) | cluster_election_state(计数未导出) | 稳态 = 17(Closed);计数不应上升 |
| Leadership term id | Cluster leadership term id (239) | (未导出) | 每次正当的 leader 更替才加一;比这更快就是churn |
| CM 周期时间 | Cluster max cycle time in ns (216) / exceeded (217) | cluster_max_cycle_time_seconds、cluster_cycle_time_threshold_exceeded_total | consensus module 的 duty-cycle 延迟 |
| Service 周期时间 | Cluster container max cycle time in ns (218) / exceeded (219) | cluster_service_max_cycle_time_seconds、cluster_service_cycle_time_threshold_exceeded_total | 你的服务代码的 duty-cycle 延迟 |
| Driver 周期时间 | Conductor/Sender/Receiver max cycle time … in ns 及 work cycle exceeded threshold count(type 0) | driver_max_cycle_time_seconds{agent}、driver_cycle_time_threshold_exceeded_total{agent} | cluster 下面那一层——核隔离失效最先在这里露出来 |
| 错误 | Cluster Errors (212) / Cluster Container Errors (215) | cluster_errors_total、cluster_service_errors_total | 单调累计——任何增量都值得一看 |
| 客户端超时 | Cluster timed out client count (213) | cluster_timed_out_clients_total | 因不活跃而被踢掉的会话——网关卡住了,或者你的会话超时设得太紧 |
| 有效快照 | Cluster snapshot count (205) | cluster_valid_snapshots | 可用快照的数量 |
| 快照年龄 | (由 recording-log 时间戳推算) | cluster_last_snapshot_timestamp_seconds | 旧快照 ⇒ 恢复时回放漫长 |
| 快照时长 | Total max snapshot duration in ns (234) / exceeded (235);单个 service 为 (236/237) | cluster_max_snapshot_duration_seconds、cluster_snapshot_duration_threshold_exceeded_total | 长快照会拖住热路径(OSS) |
| 背压 | snd-bpe (13) / Sender flow control limits | driver_sender_bpe_total(也按 streamId 分) | 「健康系统中应为零」 |
| 丢包 / NAK | NAKs sent/received、Retransmits sent(type 0) | driver_nak_messages_*_total、driver_retransmits_sent_total | 网络丢包 ⇒ 复制被拖慢 |
| Loss gap fills | Loss gap fills(type 0) | driver_loss_gap_fills_total | 被跳过而非被补回的丢包——只会出现在关掉了可靠投递的流上 |
| 畸形 / 丢弃 | Invalid packets、Short sends(type 0) | driver_invalid_packets_total、driver_short_sends_total、driver_flow_control_over_runs_total | 三者都应为零;非零说明是 MTU、socket buffer,或某个跟不上的 subscriber |
| 存活性 | (计数器更新的新鲜度) | cluster_activity_age_seconds、driver_heartbeat_age_seconds | 距该组件上次活跃过去了多少秒 |
Consensus module 状态:哪些取值该叫人
Section titled “Consensus module 状态:哪些取值该叫人”Consensus Module state (200) / cluster_consensus_module_state 是一个枚举,七个取值里只有两个是良性的。按「!= 1」告警会让你在每次打快照时都被叫起来。
| 取值 | 状态 | 如何处理 |
|---|---|---|
| 0 | INIT | 启动和恢复期间属正常。若长时间停留、超过你预期的回放时间就要叫人——卡在长 log 回放上的节点,就不在 quorum 里。 |
| 1 | ACTIVE | 健康稳态。 |
| 2 | SUSPENDED | 有人通过 ClusterControl/ClusterTool 挂起了集群,ingress 已不再被处理。叫人——生产环境里这几乎从来不是有意的。 |
| 3 | SNAPSHOT | 正常,且应当很短暂。持续不退就看快照时长那条告警。 |
| 4 | QUITTING | 节点正在退出。计划内停机属预期,否则叫人。 |
| 5 | TERMINATING | 正在关停——包括非自愿的 ClusterTerminationException 路径(例如 archive 存储耗尽)。叫人。 |
| 6 | CLOSED | 终态。节点已经没了,存活性/心跳年龄会印证这一点。 |
实操规则:2、4、5、6 立即叫人;0 只在超过一段按你的 log 回放时间设定的启动宽限期后才叫人;3 永远不要叫人——改为对它的持续时长告警。
告警:把指标映射到故障模式
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」不是文档术语——自己定速率。) |
| Leadership churn(高) | leadership term id (239) 的自增快于你计划中的切主频率 | term id 每次正当的 leader 更替才加一;没有维护动作却在爬,说明集群在反复重新选举 leader。 |
| 客户端在超时(中) | cluster_timed_out_clients_total 增量 > 0 | 会话因不活跃被踢——可能是网关/OMS 停止了轮询,也可能是会话超时比客户端最坏情况下的停顿还短。注意与 driver_client_timeouts_total 区分,后者是 media driver 的客户端,不是 cluster 会话。 |
| Follower 滞后(中) | rec-pos(log) − commit-pos 随时间增长 | leader 追加的速度快于 quorum 确认——正走向背压或 quorum 丢失。无文档化的差距阈值。 |
| 周期时间超限(中) | cycle time exceeded 计数器(217/219)在自增 | CM 与 service 的 duty-cycle 阈值默认为 100ms。尖刺 = GC / CPU 饥饿;一次 10ms 的周期就是 p99 上一个 10ms 的坑。 |
| Driver 周期时间超限(中) | driver_cycle_time_threshold_exceeded_total{agent} 在自增 | driver 的 conductor、sender、receiver 同样默认 100ms。当成因是共享核争抢或 isolcpus 失效时,它会先于 cluster 那几个计数器触发——driver 线程最先感受到。见核隔离与绑核。 |
| 错误上升(高) | Cluster Errors (212) 增量 > 0 | 然后通过 ClusterTool errors 读文本。无文档化的数值速率。 |
| 快照过旧(中) | 当前时间 − cluster_last_snapshot_timestamp_seconds > 你的恢复预算 | Aeron 中快照是手动的——旧快照意味着重启时漫长的 log 回放。见快照失败与恢复。 |
| 快照过慢(低/中) | 快照时长 exceeded (235) 在自增 | 阈值默认 1s。在 OSS 中快照会拖住热路径;在 leader 上则会体现为最大延迟的上升。 |
| 背压 / 丢包(中) | snd-bpe、NAK 或重传速率高于基线 | subscriber/follower 跟不上,或网络丢包拖慢复制。无文档化的速率阈值。 |
| 数据被静默跳过(高) | 某条 cluster 流上 driver_loss_gap_fills_total 增量 > 0 | 一次 gap fill 意味着丢包被跳过而不是补回。它只发生在非可靠流上,所以出现在 cluster 流量上就说明有人给一条不能丢数据的流配了 reliable=false。要查配置,不是查网络。 |
| 畸形帧(中) | driver_invalid_packets_total、driver_short_sends_total 或 driver_flow_control_over_runs_total 增量 > 0 | 文档明确这三个都「应为零」。invalid packets ⇒ MTU/路径问题,或有别的发送方占了这个端口;short sends ⇒ socket buffer 太小;over-runs ⇒ 同一条流里某个 receiver 落在了其他人后面。 |
| 存储耗尽(严重) | archive/cluster 卷的可用空间低于你的下限 | archive 存储耗尽会抛 ClusterTerminationException 并终止节点——这是唯一一种总是终止性的快照/archive 故障。要在它发生之前告警。 |
| 节点失联(严重) | cluster_activity_age_seconds / driver_heartbeat_age_seconds 在上升,或抓取目标掉线 | 该组件停止更新计数器——进程已死或卡死。 |
可以直接粘贴的告警规则
Section titled “可以直接粘贴的告警规则”散文式的告警条件最后都会烂掉,所以下面把同样的规则写成 PromQL。它们用的是 Insights 的指标名;自建 exporter 请替换成你自己的命名。另外注意 commit_position_total 是位置,不是计数器——对它做 rate() 得到的是每秒提交的 log 字节数,这正是你要的,但 increase() 遇到重置时会像是发生了重启。
每个 cluster 指标都带 clusterId 标签(service 还额外带 serviceId),所以凡是要归因到具体节点的表达式,都保留 by (instance, clusterId)。
groups:- name: aeron-cluster-stability rules:
# 1. Commit 停滞——集群活着,但没在提交。 # 窗口取得比 leader 心跳超时(10s)更长,避免一次正常选举把它触发。 - alert: AeronCommitStalled expr: | rate(cluster_commit_position_total[1m]) == 0 and on(instance, clusterId) cluster_consensus_module_state == 1 and on(instance, clusterId) cluster_node_role == 2 for: 15s labels: { severity: critical } annotations: summary: "Leader 处于 ACTIVE 但 commit position 已平了 15s"
# 2. 整个集群没有 leader。 - alert: AeronNoLeader expr: sum by (clusterId) (cluster_node_role == 2) == 0 for: 5s labels: { severity: critical }
# 2b. 脑裂:多于一个节点自称 leader。 - alert: AeronMultipleLeaders expr: sum by (clusterId) (cluster_node_role == 2) > 1 for: 5s labels: { severity: critical }
# 3. Leadership churn。Insights 不导出选举计数指标(见上面的提示框), # 所以退一步数角色切换。若你自己抓了计数器 238,就再加一条针对它的规则。 - alert: AeronLeadershipChurn expr: sum by (clusterId) (changes(cluster_node_role[15m])) > 2 labels: { severity: warning } annotations: summary: "15 分钟内发生了不止一次切主"
# 3b. 选举收不回来:状态卡在 17(CLOSED)之外。 - alert: AeronElectionNotSettling expr: cluster_consensus_module_state == 1 and cluster_election_state != 17 for: 30s labels: { severity: warning }
# 4. Consensus module 处于需要人介入的状态。 # 2=SUSPENDED 4=QUITTING 5=TERMINATING 6=CLOSED。3=SNAPSHOT 是良性的。 - alert: AeronConsensusModuleBadState expr: cluster_consensus_module_state == 2 or cluster_consensus_module_state >= 4 for: 10s labels: { severity: critical }
# 0=INIT 只有在持续不退时才算问题——`for` 按你的 log 回放时间来定。 - alert: AeronStuckInitialising expr: cluster_consensus_module_state == 0 for: 10m labels: { severity: warning }
# 5. Duty-cycle 超限——GC、CPU 饥饿、绑核失效。 - alert: AeronConsensusCycleBreach expr: increase(cluster_cycle_time_threshold_exceeded_total[5m]) > 0 labels: { severity: warning }
- alert: AeronServiceCycleBreach expr: increase(cluster_service_cycle_time_threshold_exceeded_total[5m]) > 0 labels: { severity: warning }
- alert: AeronDriverCycleBreach expr: increase(driver_cycle_time_threshold_exceeded_total[5m]) > 0 labels: { severity: warning } annotations: summary: "Driver {{ $labels.agent }} 的 duty cycle 超过了 100ms"
# 瓶颈在你的代码还是在 Raft?看比值,不看绝对值。 - alert: AeronServiceCodeIsBottleneck expr: | cluster_service_max_cycle_time_seconds / on(instance, clusterId) cluster_max_cycle_time_seconds > 5 for: 5m labels: { severity: warning }
# 6. 错误——对计数告警,然后用 `ClusterTool errors` 读文本。 - alert: AeronErrors expr: | increase(cluster_errors_total[5m]) > 0 or increase(cluster_service_errors_total[5m]) > 0 or increase(driver_errors_total[5m]) > 0 or increase(archive_errors_total[5m]) > 0 labels: { severity: warning }
# 7. 恢复风险:快照年龄对照你的 RTO 预算,以及慢快照。 - alert: AeronSnapshotTooOld expr: time() - cluster_last_snapshot_timestamp_seconds > 3600 labels: { severity: warning }
- alert: AeronSnapshotTooSlow expr: | increase(cluster_snapshot_duration_threshold_exceeded_total[30m]) > 0 or increase(cluster_service_snapshot_duration_threshold_exceeded_total[30m]) > 0 labels: { severity: info }
# 8. 下面那层传输。永远看变化率,不看累计总量。 - alert: AeronBackPressure expr: rate(driver_sender_bpe_total[1m]) > 0 for: 2m labels: { severity: warning }
- alert: AeronPacketLoss expr: | rate(driver_nak_messages_received_total[1m]) > 0 or rate(driver_retransmits_sent_total[1m]) > 0 for: 2m labels: { severity: warning }
# 这几个文档写明「应为零」——任何增量都是真的。 - alert: AeronShouldBeZeroCounters expr: | increase(driver_invalid_packets_total[5m]) > 0 or increase(driver_short_sends_total[5m]) > 0 or increase(driver_loss_gap_fills_total[5m]) > 0 or increase(driver_flow_control_over_runs_total[5m]) > 0 or increase(cluster_timed_out_clients_total[5m]) > 0 labels: { severity: warning }
# 9. 节点失联。两个 age 都约每秒刷新,所以 >5s 说明进程卡死或已经没了。 - alert: AeronNodeDark expr: cluster_activity_age_seconds > 5 or driver_heartbeat_age_seconds > 5 for: 10s labels: { severity: critical }按流监控:cluster 自己的 stream id
Section titled “按流监控:cluster 自己的 stream id”cluster 流量跑的就是普通的 Aeron pub/sub,所以那些 driver 层计数器(snd-bpe、NAK、重传、publisher/subscriber 位置)全都可以按流拿到——而哪条流在丢包,就告诉你这是哪一类故障。下面是默认值;它们都可以用系统属性覆盖,所以请照你自己的配置读,不要想当然。
| Stream id | 流 | 配置项 | 这里丢包意味着 |
|---|---|---|---|
100 | Cluster log(leader → follower) | aeron.cluster.log.stream.id | 复制被拖慢——append−commit 差距扩大,接着丢 quorum |
101 | Ingress(客户端 → leader) | aeron.cluster.ingress.stream.id | 客户端到不了 leader;这里的背压会节流你的网关 |
102 | Egress(leader → 客户端) | aeron.cluster.egress.stream.id | ack/响应在丢——客户端重试或超时 |
103 | Service replay(archive → service) | aeron.cluster.replay.stream.id | 重启时恢复/回放变慢 |
104 | Service → consensus module | aeron.cluster.service.stream.id | service 没法向 CM 汇报进度 |
105 | Consensus module → service | aeron.cluster.consensus.module.stream.id | service 没有被驱动 |
106 | Service 快照 | aeron.cluster.snapshot.stream.id | 快照写入路径 |
107 | Consensus module 快照 | (同一个属性,默认值不同) | 快照写入路径 |
108 | Consensus(节点间:投票、心跳、canvass) | aeron.cluster.consensus.stream.id | 这里丢包才是真正触发选举的原因——心跳和投票请求在丢 |
106/107 这个区分只是默认值造成的表象:consensus module 和 service container 读的是同一个 aeron.cluster.snapshot.stream.id 属性,只是默认值不同(107 和 106)。一旦显式配置该属性,两者就会塌到同一个 stream id 上——所以如果你的仪表盘靠 stream id 去区分这两条快照路径,只要有人配了这个属性,它立刻就失效。
要和操作系统一起看,否则会误诊
Section titled “要和操作系统一起看,否则会误诊”「集群不稳」这类故障,只要真实成因是 GC、被抢走的核,或者打满的网卡,在 Aeron 的计数器里看起来都一模一样:周期时间超限加选举。计数器告诉你的是duty cycle 停滞了,它没法告诉你为什么。Aeron 自己的排障指南之所以要指向运行队列长度、swap 和线程调度,正是因为这个——所以请把下面这些放在同一条时间轴上一起采:
| 检查项 | 命令 | 你在找什么 |
|---|---|---|
| 运行队列 / 上下文切换 | vmstat 1 | r 列长期高于核数 ⇒ driver 和 CM 线程正在被调度走。cs 出现尖刺 ⇒ 有别的东西落到了它们的核上。si/so(swap)只要非零,这台机器就不该跑低延迟。 |
| 每核 steal / softirq | mpstat -P ALL 1 | 虚拟化宿主上的 %steal,或者你隔离出来的那些核上的 %soft/%irq——任何一个都说明你并没有真正独占你绑定的那个核。 |
| UDP 数据报错误 | sar -n UDP 1 / netstat -su | idgm_err、接收缓冲区错误和 noport 与 Aeron 的 NAK 同步上升,就确认了丢包发生在 Aeron 之下——是内核 socket buffer 或网卡 ring,不是协议。见接收路径缓冲区。 |
| 网卡丢弃 | ethtool -S <if> | grep -i drop、ip -s link | rx_dropped/rx_no_buffer ⇒ ring buffer 太小,或者接收路径跟不上。 |
| GC 停顿 | JVM GC 日志(-Xlog:gc*,或 -Xlog:safepoint) | 任何接近 100ms duty-cycle 阈值的停顿都能解释一次周期超限;任何接近 10s 心跳超时的停顿都能解释一次选举。真正重要的数字是 safepoint 时间,不是 GC 时间。 |
| 磁盘延迟(follower 也要看) | iostat -x 1 | archive 卷上的 await——一块慢的 follower 磁盘会拖住整个集群,因为 commit 要等 quorum,而 quorum 要等最慢的那个确认者。 |
仪表盘上到底该放什么
Section titled “仪表盘上到底该放什么”如果你只搭一组面板,就照这个来——从上到下按你排障的顺序排列:
- 它还活着吗? 每个节点的角色(恰好一个 Leader)、存活/心跳年龄、抓取目标是否在线。
- 它在推进吗? commit-position 速率(你真正的吞吐量)以及 append−commit 差距。
- 它稳定吗? 选举计数(一条平线 = 健康)以及 consensus-module 状态。
- 瓶颈是你的代码吗? service 周期时间 vs. consensus 周期时间——若 service ≫ consensus,问题在你的 handler,而非 Raft。
- 底层健康吗? 背压、NAK/重传速率、archive/磁盘可用空间——并且按 stream id 拆开,让 consensus 流丢包(选举)和 log 流丢包(滞后)一眼就能分开。
- 你能快速恢复吗? 快照年龄、有效快照数、快照时长超限。
- 该怪机器吗? 运行队列、
%steal、safepoint 停顿、UDP 错误——和上面所有面板画在同一条时间轴上,否则每次故障的头二十分钟都花在弄清这件事上。
- 计数器模型:
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。 - 本页的 stream id、状态枚举和计数器 type id 均直接读自
ConsensusModule.java(State0–6;log 100、consensus 108、snapshot 107;aeron.cluster.cycle.threshold= 100ms)、AeronCluster.java(ingress 101、egress 102)、ClusteredServiceContainer.java(replay 103、service 104、consensus-module 105、snapshot 106)、AeronCounters.java(213 client-timeout、236/237 单个 service 的快照时长、239 leadership-term id),以及SystemCounterDescriptor.java(Loss gap fills、Invalid packets、conductor/sender/receiver 的周期时间标签;aeron.driver.*.cycle.threshold= 100ms)。 - 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 在英国及其他国家/地区的商标。