部署于EC2 Docker的NodeJS生产应用随机停止响应求助
排查NodeJS后端Docker部署后随机无响应问题(EC2+AWS RDS MySQL)
问题背景
我有一个NodeJS后端应用,通过Docker部署在EC2实例上,连接AWS RDS MySQL数据库。应用会在随机时间点出现接收请求后无响应的情况,相关请求日志(格式:时间 接口 响应状态 响应时间 响应体大小)如下:
14:26:02 "PUT /api/invoices/collect" 200 11 ms 4 14:26:02 "GET /api/invoices/47158" 200 25 ms 2266 14:26:19 "GET /api/invoices/customer/1488?type=ITEMS_INVOICE" 200 5 ms 2 14:26:20 "GET /api/items/company/1?isActive=true" 200 10 ms 5286 14:27:20 "GET /api/plans/?isActive=true" 200 13 ms 3644 14:28:57 "PATCH /api/users/1488/plans" - - ms - 14:29:04 "PATCH /api/users/1488/plans" - - ms - 14:29:07 "GET /api/level3-addresses/" - - ms - 14:29:08 "PATCH /api/users/1488/plans" - - ms - 14:29:28 "PATCH /api/users/1488/plans" - - ms - 14:29:29 "GET /api/level3-addresses/" - - ms -
目前仅能通过执行docker-compose restart backend重启应用(重启后会重新运行node dist/src/main)恢复正常,已尝试升级EC2实例规格,但问题仍存在,寻求解决方案。
排查步骤与解决方案
1. 检查数据库连接池与阻塞问题
- 核对NodeJS应用的数据库连接配置,确认是否设置了合理的连接池大小、连接超时和空闲连接回收机制。连接池耗尽、连接未正确释放(如未捕获异常导致连接挂起)会直接导致后续请求无法获取连接而阻塞。
- 启用AWS RDS的性能Insights,查看无响应时段的数据库会话状态,执行
SHOW PROCESSLIST;检查是否有长时间运行的查询、锁等待,或是Sleep状态连接过多占满连接数的情况。 - 确认应用是否正确处理数据库操作错误,比如查询超时后主动释放连接,避免连接泄漏。
2. 排查NodeJS事件循环阻塞
- 在应用中添加事件循环监控,比如用
process.nextTick或clinic.js工具检测是否存在CPU密集型任务、同步IO、长时间运行的Promise阻塞事件循环——这会导致请求无法被正常处理。 - 排查无响应前最后成功的请求(比如
GET /api/plans/?isActive=true)对应的业务逻辑,检查是否存在同步操作、大量数据处理或未异步化的代码。 - 无响应时执行
docker stats或进入容器执行top,查看NodeJS进程的CPU、内存占用,确认是否出现CPU满负载或内存耗尽(即使升级了EC2,容器自身可能有资源限制)。
3. 检查Docker与EC2的网络及资源配置
- 核对EC2到RDS的安全组规则,查看CloudWatch网络监控,确认是否存在临时网络中断、数据包丢失或延迟突增的情况。
- 检查
docker-compose.yml中是否给backend容器设置了资源限制(如cpus、memory),过低的资源限制会导致高负载时应用无法分配足够资源而挂起。 - 执行
docker logs <backend-container-id>查看容器内部日志,排查是否有进程崩溃、OOM Killer触发的记录。
4. 检查请求处理中的异常与内存泄漏
- 给NodeJS应用添加未捕获异常和未处理Promise拒绝的监听,避免进程进入异常状态却不崩溃:
process.on('uncaughtException', (err) => { console.error('Uncaught Exception:', err); }); process.on('unhandledRejection', (reason, promise) => { console.error('Unhandled Rejection at:', promise, 'reason:', reason); }); - 用
node --inspect dist/src/main启动应用,无响应时通过Chrome DevTools连接进程,查看内存快照排查是否存在内存泄漏。
5. 临时自动恢复方案
- 在
docker-compose.yml中给backend服务添加restart: on-failure,让Docker在进程异常时自动重启应用,减少手动操作成本。 - 结合CloudWatch设置告警规则,当请求失败率达到阈值时,自动触发EC2上的脚本执行
docker-compose restart backend。
内容的提问来源于stack exchange,提问作者Ali Kashmar
相关产品推荐
相关产品推荐

