🧩 问题描述
线上生产环境中,Supervisor 用于守护多个 PHP 脚本任务(共计 310 个)。这些脚本长期运行,一直有正常的日志输出。然而在某天突然发现:
- 某任务的日志输出中断;
- 执行
supervisorctl status
显示任务状态为 RUNNING,没有异常; - 但实际进程未运行、无任何日志产出;
- 尝试
supervisorctl restart
无效,任务仍然假运行,没有报错。
同时排查系统资源:
- 磁盘空间充足;
- CPU、内存无明显瓶颈;
任务脚本代码无更新,排除人为逻辑问题。
🔍 日志排查
查看 supervisord.log
,发现有如下记录:
2025-07-23 18:22:18,057 INFO waiting for check-test-100 to stop
2025-07-23 18:22:18,061 INFO stopped: check-test-100 (terminated by SIGTERM)
2025-07-23 18:22:18,129 INFO spawned: 'check-test-100' with pid 17587
2025-07-23 18:22:19,132 INFO success: check-test-100 entered RUNNING state, process has stayed up for > than 1 seconds (startsecs)
从日志来看,Supervisor 确实重新拉起了该任务,但实际上脚本未真正运行。
🧠 问题分析
这是一个经典的「假活着」问题:Supervisor 判定进程已启动(达到了 startsecs
),但进程并未真正进入业务逻辑运行状态。更糟的是,Supervisor 无法识别该异常状态,导致无法自动修复。
结合系统配置排查,发现如下设置:
cat /proc/sys/net/core/somaxconn
128
该值表示 监听套接字的最大等待连接队列长度,默认是 128
。当并发连接数暴增时(如高频脚本启动、网络通信等),连接排队超过此限制,可能导致:
- 脚本运行时阻塞;
- Supervisor 启动进程虽然返回成功,但业务逻辑卡在 socket 阶段;
- 表面是 RUNNING,实际任务处于假死或 hang 住状态。
🛠️ 运维解决方案
调整内核参数:
- 修改配置文件:
vim /etc/sysctl.conf
添加:
net.core.somaxconn = 2048
- 立即生效:
sysctl -p
该修改将 somaxconn
的默认值由 128
提升至 2048
,允许更多并发连接排队,有效缓解 socket 阻塞问题。
✅ 效果验证
配置修改后,重启相关 Supervisor 任务,观察日志输出恢复正常,任务确实执行逻辑,并产生日志,问题解决。
如需进一步稳定,可以考虑:
- 为脚本添加健康检查机制,配合
autorestart=false
实现业务层自我修复; - 限制 Supervisor 启动进程速率,避免短时间高并发;
- 监控 socket backlog 队列使用情况。