Karp 的技术博客

🧩 问题描述

线上生产环境中,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 住状态。

🛠️ 运维解决方案

调整内核参数:

  1. 修改配置文件:
vim /etc/sysctl.conf

添加:

net.core.somaxconn = 2048
  1. 立即生效:
sysctl -p

该修改将 somaxconn 的默认值由 128 提升至 2048,允许更多并发连接排队,有效缓解 socket 阻塞问题。

✅ 效果验证

配置修改后,重启相关 Supervisor 任务,观察日志输出恢复正常,任务确实执行逻辑,并产生日志,问题解决。


如需进一步稳定,可以考虑:

  • 为脚本添加健康检查机制,配合 autorestart=false 实现业务层自我修复;
  • 限制 Supervisor 启动进程速率,避免短时间高并发;
  • 监控 socket backlog 队列使用情况。

Supervisor

版权属于:karp
作品采用:本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
更新于: 2025年08月04日 08:35
2

目录

来自 《Supervisor 守护 PHP 脚本日志中断问题排查记录》