在使用 supervisord
管理大量服务时,笔者遇到了一个奇怪的问题:当任务数量接近 200 个时,新的服务启动会失败,而 supervisor 本身没有明确报错信息。经过排查,最终确认是系统资源限制(如打开文件数、进程数)导致的问题,并通过调整配置成功解决。
💥 问题描述
当 supervisord
启动约 200 个任务之后:
- 新增的服务(program)无法正常启动
- 日志中没有明显报错,偶尔出现资源相关的提示
- 手动启动服务进程则正常运行
这表明 supervisord
自身没有问题,而是其子进程启动失败。
🔍 问题分析
Linux 系统对每个用户/进程的资源使用是有限制的。最常见的两个限制如下:
NOFILE
:一个进程最多可打开的文件描述符数量(包括 socket)NPROC
:一个用户最多可创建的进程数
默认情况下,很多 Linux 发行版会把这两个值设得比较小(例如 1024 或 4096),这在管理大量服务时很容易触发限制。
✅ 解决方案
1. 修改 supervisor 的 systemd 启动限制
如果你使用 systemd
启动 supervisord
(大多数现代 Linux 系统如此),需要修改或创建其服务文件:
sudo vim /etc/systemd/system/supervisord.service
在 [Service]
部分添加或修改以下内容:
[Service]
LimitNOFILE=8888
LimitNPROC=65535
保存后执行以下命令使配置生效:
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl restart supervisord
2. 修改用户级资源限制(可选)
为了彻底消除限制,建议同时修改系统用户限制配置:
编辑 /etc/security/limits.conf
:
* soft nofile 8888
* hard nofile 8888
* soft nproc 65535
* hard nproc 65535
确保 PAM 模块启用资源限制,在 /etc/pam.d/common-session
或 /etc/pam.d/su
中包含如下内容:
session required pam_limits.so
3. 验证是否生效
切换到对应用户(如 supervisord
启动用户)下,运行:
ulimit -n # 应为 8888
ulimit -u # 应为 65535
如果仍不正确,尝试重新登录或重启服务器。
🛠 补充建议
在 supervisor.conf
或 program 配置块中,建议添加以下内容以便调试和稳定运行:
[program:your-service]
command=/path/to/your-service
autorestart=true
stderr_logfile=/var/log/supervisor/your-service.err.log
这样即使服务因资源限制失败,也能通过日志查看具体原因。
🧾 总结
在大量使用 supervisord
管理进程时,务必关注系统级资源限制。合理地设置 LimitNOFILE
和 LimitNPROC
,可以让你的服务扩展更加平滑。
✅ 修改 systemd 启动参数
✅ 修改用户级 ulimit
✅ 验证配置是否生效
✅ 补充日志配置方便调试