Edge 与中心失联
边缘断网期间判定和通知照常在本地进行,但事件不会回传中心——这是预期行为;从未连上过才是配置错误,两者的判断方法不同。
系统配置 → 告警引擎里那个边缘实例的心跳停了,或者整行消失了; 或者机房里的人收到了告警,中心的事件列表却一条都没有。
后面这个才是本页的重点现象:有人被叫醒了,系统里查无此事。 这是断网期间的预期行为,不是故障——先弄清这一点,能省掉大半的排查。
先分清「断网」和「从来没连上」
这一步定方向,两个方向的排查完全不同:
| 问自己 | 结论 |
|---|---|
| 这个 edge 以前正常出现过在告警引擎列表里吗 | 出现过 → 是真断网,看下面「断网期间什么还在工作」 |
| 从部署到现在一次都没出现过 | 是配置问题,看下面前两个根因 |
判据很硬:跑着的 edge 能无限期扛过断网,正在启动的 edge 扛不过。
启动时它要做一次完整的配置同步,十几个缓存里任何一个同步失败都会直接 exit(1)——
不会降级运行,是立刻硬退。所以「进程起不来」和「进程活着但心跳没了」是两件事:
前者一定是配置或网络在启动那一刻就不通,后者才是断网。
顺带:edge 需要自己的 Redis,不能和中心共用;启动时连不上 Redis 同样直接退出。
断网期间什么还在工作,什么不在
edge 每 9 秒从中心拉一次配置放在内存里。拉取失败时缓存保留上一份好的、永不清空, 一致性哈希环也不重建,所以规则归属在断网期间是冻结的。这是刻意设计。
| 能力 | 断网期间 |
|---|---|
| 规则判定 | 继续,用最后一次同步到的规则,查本机房自己的数据源 |
| 屏蔽、订阅、工作流 | 继续,用最后一次同步到的配置 |
| 发通知 | 继续,而且是从 edge 直接发出去的,不经过中心 |
| 判定记录(evallog) | 继续,写在 edge 自己的本地磁盘上 |
| 新建 / 修改规则 | 停止。中心改的规则,链路恢复前 edge 看不到 |
「通知从 edge 直接发出去」有一个容易漏掉的网络前提: 边缘机房必须能直连钉钉、飞书、企业微信、你的 SMTP 和各个 webhook 地址。 只放行了「edge → 中心」的防火墙,断网时照样发不出通知。
断网期间产生的事件会永久丢失
这是本页最重要的一节。
edge 产生的事件要 POST 到中心的 /v1/n9e/event-persist 才能落库。断网时这个 POST
重试 3 轮(初始间隔 100 毫秒、逐轮翻倍、单次超时 2 秒,单地址最坏约 6.3 秒),
然后事件被丢弃。没有本地队列、没有磁盘暂存、链路恢复后也不会补。
后果:
- 告警事件表里没有这一行,活跃事件和历史事件里都查不到;
- 事件 ID 是 0,于是通知记录和模板里的
event_id也都是 0; - 通知记录本身也丢了——它是一次没有任何重试的 POST。
但通知照发:落库失败从不阻断发送。所以断网期间的真实体验就是那句 「有人收到了告警,系统里没有记录」。
怎么确认是它:到 edge 自己的 /metrics(端口 19000)上看这个:
curl -s --noproxy '*' http://n9e-edge:19000/metrics \
| grep 'n9e_alert_rule_eval_error_total' | grep 'persist_event'
stage="persist_event" 这一维只在事件落库失败时增长,是断网丢事件最直接的计数。
edge 日志里同时有:
ERROR event:<事件哈希> persist err:<错误>
另外内存里那个上千万上限的事件队列不是断网缓冲——消费者一直在排空, 落库失败也不阻塞,所以它根本不会堆积起来。
常见根因与确认方法
中心的 APIForService 没开——出厂默认就是关的
edge 拉配置走的是中心的 /v1/n9e/*,这组接口由 [HTTP.APIForService] 控制,
而它在 etc/config.toml 里的出厂值是 Enable = false。
所以「新部署的 edge 一次都没连上」绝大多数是这一条。
怎么确认:edge 日志里反复出现对 /v1/n9e/... 的请求失败;
中心那边这个端点直接不存在。BasicAuth 对不上则是 401。
怎么修:中心和 edge 两边都要配,用户名口令必须一致:
# 中心的 etc/config.toml
[HTTP.APIForService]
Enable = true
[HTTP.APIForService.BasicAuth]
user001 = "<把出厂默认口令换掉>"
# edge 的 etc/edge/edge.toml
[CenterApi]
Addrs = ["http://n9e:17000"]
BasicAuthUser = "user001"
BasicAuthPass = "<和上面一致>"
Timeout = 9000
Addrs 配多个时是依次尝试、第一个成功就用,不是并发广播。
还有一处同名配置容易漏:想在中心的界面上看 edge 的判定记录,
edge 自己的 [HTTP.APIForService] 也要 Enable = true(它的出厂值同样是 false),
口令和中心一致——中心是拿自己的凭据去转发这个请求的。
启动时指错了配置目录
n9e-edge --configs etc/edge
--configs 的默认值是 etc,而 etc 下放的是中心的 config.toml。
指错了它会当成中心配置加载,不报错,行为却完全不对。
怎么确认:看进程启动命令行;再看 edge 的监听端口是不是 19000
(etc/edge/edge.toml 里的 [HTTP] Port)。听成 17000 就是加载了中心那份配置。
心跳集群名也是线索:etc/edge/edge.toml 里 EngineName = "edge",
中心那份是 "default"——告警引擎页面上这个实例归在哪个集群下,直接说明它读了哪份配置。
怎么修:把 --configs etc/edge 补上,重启。
边缘到通知媒介的网络没开
怎么确认:从 edge 那台机器上直接 curl 一次 webhook 地址或 telnet SMTP 端口。 中心能通不代表 edge 能通——断网时发信的是 edge。
怎么修:按 edge 所在机房的出向策略开通,而不是按中心的。
断网期间重启了 edge
跑着的 edge 能扛过断网,重启一次就再也起不来了,直到链路恢复。 这会把「还在告警」变成「完全不告警」,是本页破坏力最大的一种。
怎么确认:进程根本不在,日志末尾是启动阶段的配置同步失败。
怎么修:断网期间不要重启、不要升级、不要改 edge 的配置文件。 提前检查 supervisor / systemd 的自动重启策略,别让它在断网时自动帮你重启一次。
确认恢复了
链路恢复后不需要任何手工操作,也没有任何手工操作可做。按这个顺序确认:
- 系统配置 → 告警引擎,这个 edge 实例重新出现,
归在
EngineName指定的集群下,最近心跳在跳动。 (超过 30 秒没心跳的行会被移出列表,所以「行在且时间在动」是硬指标;) - edge 日志里不再有
/v1/n9e/...的请求失败——配置缓存会在下一个 9 秒周期追上; n9e_alert_rule_eval_error_total{stage="persist_event"}停止增长;- 在中心的事件列表里,能看到这个边缘机房新产生的事件;
- 挑一条这个机房的规则做测试触发,走完查询、判定、事件、通知一整条。
断网期间丢掉的事件和通知记录不会回来,没有补写机制。 那段时间唯一留存的证据是 edge 本地磁盘上的判定记录——它不依赖中心。
还有一个正常现象:中心其实已经提交、只是响应丢了的那个窄窗口里,重试会再插一条历史事件。 断网之后偶尔看到重复的历史事件是预期的。
收集这些再去提问
- edge 的启动命令行(重点是
--configs)和etc/edge/edge.toml全文; - 中心
etc/config.toml里[HTTP.APIForService]那一节; - 断网时间段内 edge 的日志,重点是
/v1/n9e/和persist err:两类行; curl --noproxy '*' http://n9e-edge:19000/metrics | grep n9e_alert_rule_eval_error_total;- 告警引擎页面的截图或那一行的内容(实例、集群名、最近心跳)。
脱敏:BasicAuthPass、Redis 口令、通知媒介的 webhook 和 token 一律替换;
机房地址写成 n9e-edge:19000、n9e:17000 这样的占位。
stage= 后面的值和错误文本要原样保留。
下一步
- 断网期间的完整行为模型:Edge 断网行为
- edge 怎么部署:边缘机房
- 部署形态怎么选:生产拓扑
- 事件产生了但没通知:有事件但收不到通知
- 中心侧也没数据:数据源连接正常但查询无数据