PM2托管NodeJs+Express+Mongodb应用每秒崩溃重启循环问题排查
问题根因拆解
- 触发秒级循环重启的直接触发源是
server.js:987抛出的未捕获TypeError: Cannot read property 'db' of undefined,本质是Mongo连接回调返回了空的客户端实例,代码直接对空对象取.db属性导致进程崩溃,和业务代码本身的逻辑缺陷无关。 - 状态变化的时间线完全匹配故障逻辑:删除
mongo.conf后无配置约束的Mongo服务连续无异常跑了24小时,之后因为资源耗尽、权限异常、磁盘句柄占满等问题进入不可用状态,Node应用每次尝试建立Mongo连接都超时失败,回调拿到空实例后直接抛错退出进程,PM2检测到进程退出后立刻拉起,就形成了日志中看到的秒级重启循环。 - 日志中的其余两类输出均为非阻塞告警,不会触发进程崩溃:
- moment库的区域设置方法弃用提示,仅为版本兼容警告,对业务逻辑无影响
MongoError属性循环依赖的警告,是mongodb驱动和Node版本匹配带来的兼容提示,不影响实际连接逻辑
分步解决操作
- 优先核查MongoDB独立运行状态:
- 执行
systemctl status mongod确认服务是否已宕机,执行mongosh验证是否能正常建立本地Mongo连接 - 补全缺失的
mongo.conf核心配置:明确数据存储路径、运行用户权限、日志输出路径、端口绑定范围、内存使用阈值,避免无配置约束的Mongo长期运行后资源耗尽崩溃
- 执行
- 修复Node应用的连接容错逻辑:
- 在
server.js第987行对应的Mongo连接回调分支,增加对客户端实例的空值判断,连接失败时执行延迟重连逻辑,不要因为连接拿不到实例就抛未捕获错误让进程退出
- 在
- 调整PM2配置避免无意义空转:
- 为server进程配置
restart_delay: 5000,即进程退出后等待5秒再尝试拉起,避免Mongo不可用时应用高频空转消耗VPS资源
- 为server进程配置
认知误区澄清
- 本地环境正常运行不代表线上代码有问题:本地Mongo配置完整、资源充足,连接长期处于稳定状态,根本不会走到连接超时的分支,自然不会触发空值报错
- 日志中的SIGINT退出信号不是外部进程恶意杀服务:这是未捕获错误触发进程退出时,PM2记录的标准退出信号标识
内容的提问来源于stack exchange,提问作者GrindCode
相关产品推荐
相关产品推荐

