故障现象:管理页面进不去 / 15个服务离线 实际根因:一块9.6G的小分区只剩1.9G
导读:某企业的智能物联综合管理平台(一体机,56个服务)突然无法登录,运维中心显示15个服务离线,客户自行重启服务器无效,故障已持续近三周。我们远程介入后,从磁盘、内存、守护进程、消息队列一路排到应用容器日志,最终定位根因:消息队列数据分区剩余空间跌破2GB安全水位,MQ自动封锁全部消息发布,连锁拖垮了承载登录服务的整个应用容器。清理1.5G历史日志后,从报警解除到平台恢复登录,全程约80分钟。
一、现场情况
| 项目 | 内容 |
|---|---|
| 设备 | 智能物联综合管理平台一体机(国产安防品牌,x86准服务器) |
| 系统 | 定制 Linux,31G 内存 / 多 LVM 分区,服务总数 56 |
| 故障现象 | Web 管理平台无法登录(登录页可开,认证失败);运维中心显示 15 个服务离线 |
| 故障时长 | 约 20 天(期间多次重启无效) |
| 架构 | 非容器化:原生 Java 进程 + keeper 守护脚本;13 个基础服务以 webapp 形式部署在同一个应用容器(Tomcat)内;消息队列 RabbitMQ、注册中心、API 网关独立进程 |
这类一体机的特点:服务之间强依赖(注册中心→MQ→业务服务→登录认证),任何一环异常都会表现为“平台进不去”,但真实故障点可能离登录页面很远。排查思路必须自底向上:资源 → 中间件 → 应用容器 → 业务服务。
二、排查过程
2.1 资源三件套:先排除磁盘/内存/负载
df -h
free -g
uptime
结果:内存充足(可用16G)、根分区健康,但发现一个可疑点——消息队列数据分区使用率 81%:
/dev/mapper/vg_storage18032-lv_rabbitmq 9.6G 7.8G 1.9G 81% /bis_data/rabbitmq
1.9G 这个数字先记下,它 later 成为整个故障的主角。
2.2 守护体系与应用容器状态
systemctl list-units --failed # 仅 abrt/kdump,业务服务不归 systemd 管
ps -ef | grep java | grep -v grep | wc -l # 只有 10 个(全量应 40+)
ps -ef | grep keeper | grep -v grep # 约50个守护脚本在跑,守护体系正常
Java 进程数明显偏少。进一步确认登录认证服务(oauth)状态:它是应用容器里的 webapp 而非独立进程,于是直接探测容器端口:
curl -s -o /dev/null -w "8080:%{http_code}\n" http://127.0.0.1:8080/evo-oauth/
# 输出 8080:000 —— 连接失败,应用容器的服务端口根本没监听
容器进程活着(6G 堆),但 8080 不监听。这说明:webapp 部署阶段失败,容器放弃了端口绑定。翻容器日志找部署失败的原始异常:
grep -nE "SEVERE|OutOfMemory|Error starting" catalina.out | head
命中关键行:
Error starting ApplicationContext ...
SEVERE A child container failed during start
SEVERE The required Server component failed to start so Tomcat is unable to start.
再看失败 webapp 的具体异常:
[evo-event][BusinessHandler][ERROR] handleBusiness error
com.rabbitmq.client.ChannelContinuationTimeoutException:
Continuation call for method channel.open on channel
AMQChannel(amqp://***@<服务器IP>:5673/,13) timed out
[evo-event][RegisterHelper][ERROR] all register-servers disabled
链条浮出水面:事件服务(evo-event)连不上消息队列 → Spring 上下文启动失败 → 一个 webapp 失败拖垮整个容器 → 13 个基础服务全灭 → 登录认证不可用。
2.3 消息队列:进程活着,为什么连不上?
MQ 端口 5672/5673/15672 都在监听,进程健康。查 MQ 自身日志,抓到真凶:
grep -iE "memory|disk|alarm" /log/VCS/RabbitMQ/Log/dahuacloud.log
Disk free limit set to 2000MB
Free disk space is insufficient. Free bytes: 1952337920. Limit: 2000000000
disk resource limit alarm set on node ...
*** Publishers will be blocked until this alarm clears ***
RabbitMQ 的自我保护机制:数据分区剩余空间低于 2GB 水位线时,自动封锁所有消息发布并阻塞连接操作。剩余 1.86G,差 150MB 触发红线——所以 MQ “活着但拒绝服务”,下游的事件服务连接超时,最终把应用容器拖死。
这也解释了为什么客户重启服务器无效:磁盘占用不会因重启减少,水位报警每次开机后重新触发,故障循环重演。
三、处置过程
3.1 定位空间大头
du -sh /bis_data/rabbitmq/RabbitMQ0/* | sort -rh | head
# 6.1G Config(mnesia消息存储) 1.6G Log(历史轮转日志) 90M Bin
ls -lhS /bis_data/rabbitmq/RabbitMQ0/Log/ | head
# 30 个 HAModule_log_*.log,每个 51M,最早到 3 个月前
3.2 清理历史轮转日志(安全操作,保留最近一份)
cd /bis_data/rabbitmq/RabbitMQ0/Log
ls HAModule_log_*.log | grep -v "HAModule_log_1.log" | xargs rm -f
df -h /bis_data/rabbitmq
# 剩余空间 1.9G → 3.5G,越过 2GB 水位线
3.3 确认报警自动解除(无需重启 MQ)
tail -5 /log/VCS/RabbitMQ/Log/dahuacloud.log
# Free disk space is sufficient. Free bytes: 3525472256. Limit: 2000000000
# disk resource limit alarm cleared on node ...
# disk resource limit alarm cleared across the cluster
RabbitMQ 每 10 秒左右重新检测磁盘,空间达标后自动解除封锁——这是很多同行不知道的点,处置时不必重启 MQ。
3.4 重启应用容器,重新部署 13 个 webapp
通过运维中心重启核心应用容器(走正规通道,自带依赖顺序与守护)。重启后登录页可打开,但提示“获取平台加密狗信息失败”——第二层问题:授权服务(EncryptDogService)比应用容器晚启动,认证模块初始化时授权服务未就绪,属于启动时序问题。
3.5 整机重启,恢复
确认 MQ 报警已解除、内存空闲充足后执行整机重启,让全部服务按正常时序拉起。重启后约 25 分钟:
ps -ef | grep java | grep -v grep | wc -l # Java 进程恢复到正常数量
netstat -tlnp | grep -E ":8080|:8921" # 应用容器与授权服务端口均监听
浏览器登录验证:管理平台正常进入,运维中心服务离线数清零。故障排除。
四、处置结果
| 指标 | 处置前 | 处置后 |
|---|---|---|
| 平台登录 | 认证失败,无法进入 | 正常登录 |
| 离线服务数 | 15 / 56 | 0 / 56 |
| MQ 数据分区剩余 | 1.9G(低于2G水位,发布封锁) | 3.5G(报警解除) |
| 应用容器 8080 端口 | 不监听(部署失败) | 正常监听,13个webapp全部部署 |
| 故障持续时间 | 约20天(多次重启无效) | 远程介入约80分钟恢复 |
五、可复用经验与避坑清单
1. “平台进不去”≠登录服务坏了,先查依赖链。 认证服务依赖消息队列、注册中心,MQ 的一个磁盘水位报警就能隔三层把登录打死。自底向上排查:资源→中间件→容器→业务。
2. RabbitMQ 磁盘水位是隐形炸弹。 默认 disk_free_limit 2GB,数据分区偏小的一体机极易触发;触发后 MQ 进程健康、端口正常,但封锁发布、阻塞连接,表面看像“MQ 没问题”。日志关键字:Publishers will be blocked。
3. 空间达标后报警自动解除,不必重启 MQ。 RabbitMQ 周期性复检磁盘,清完空间等 10 秒看日志出现 alarm cleared 即可,重启反而扩大影响面。
4. Tomcat 类容器:端口不监听=webapp 部署失败。 容器进程活着但 8080 不通,说明部署阶段有 webapp 的 Spring 上下文启动失败,容器整体放弃。直接 grep "Error starting ApplicationContext" 找第一个失败者,别被后面的 classloader stopped 刷屏干扰。
5. 多 webapp 共容器架构,一损俱损。 13 个基础服务塞在同一个容器里,任何一个失败全体陪葬。这是此类一体机的架构性弱点,排障时要有预期。
6. 重启无效≈资源类故障。 客户重启多次无效是重要信号:磁盘占用、消息堆积不会因重启消失。遇到“重启就好/重启没用”要先问自己哪类故障符合这个特征。
7. 报错要区分“根因”与“背景噪音”。 本机加密狗硬件检测常年报错(无USB硬狗、软授权模式),与本次故障无关。抓主要矛盾:看报错出现的时间点是否与故障窗口吻合。
8. 消息堆积要治本。 平台宕机 20 天,无人消费的告警/事件消息把存储堆到 6.1G。恢复后应定期巡检队列深度(rabbitmqctl list_queues),对堆积队列评估 purge,并给数据分区扩容——否则几个月后同一故障重演。
服务说明:郑州晋元网络科技有限公司提供服务器/数据库/中间件故障排查、等保合规整改、虚拟化与容器平台运维、安防物联平台维护、AI 基础设施部署等 IT 运维外包服务,支持远程与驻场,7×24 应急响应。
www.cnaibot.com