supervisor 托管 hyperf 定时任务需用绝对路径、禁用 --daemonize、前台运行;startsecs=10 避免误重启;日志分离:supervisor 捕获启动错误,hyperf 自身写业务日志;显式声明 environment 和 user。

Supervisor 托管 Hyperf 定时任务(如 php bin/hyperf.php start 启动的 Worker 进程)时,不能直接复用 Web 服务的配置——定时任务本质是长期运行的 CLI 进程,对启动逻辑、环境变量、日志捕获和存活判定更敏感。配置不当容易出现“看似运行实则静默退出”“重复拉起导致任务重复执行”“日志为空无法排障”等问题。
必须使用绝对路径并禁用守护模式
Hyperf 定时任务默认启用 Swoole 的 --daemonize 模式,一旦开启,进程会 fork 后退出前台,Supervisor 就无法接管其标准输出,也无法感知真实状态,极易误判为“启动失败”。
- 在
command=中显式去掉--daemonize(Hyperf 默认不带该参数,但需确认),确保进程始终以前台模式运行 - PHP 解释器路径必须用
which php查出绝对路径(如/usr/bin/php),不能写php - 项目路径必须用绝对路径,例如
/var/www/my-app,且directory=必须设为此路径,否则注解扫描、配置加载会失败 - 完整命令示例:
command=/usr/bin/php /var/www/my-app/bin/hyperf.php start
合理设置启动等待与重试策略
Hyperf 定时任务启动需加载容器、连接 Redis/DB、扫描命令等,耗时通常 5–15 秒。若 startsecs 过小(如默认 1 秒),Supervisor 会反复 kill 并重启进程,造成端口冲突或任务重复触发。
-
startsecs=10:建议设为 10,给足初始化时间 -
startretries=3:保留默认值,避免无限重试掩盖真实错误 -
autorestart=true+autostart=true:保持自动拉起能力 - 慎用
stopwaitsecs:定时任务无优雅关闭逻辑,设为 5–10 即可,避免阻塞重启
分离日志,兼顾启动期与运行期可观测性
Supervisor 的 stdout_logfile 和 stderr_logfile 主要用于捕获启动阶段错误(如依赖缺失、端口占用、autoload 失败)。而任务运行中的业务日志应由 Hyperf 自身 logger 写入文件,二者互补。
-
stdout_logfile=/var/log/supervisor/my-task-stdout.log:记录启动输出,保留前 10MB,自动轮转 -
stderr_logfile=/var/log/supervisor/my-task-stderr.log:专捕异常堆栈 - Hyperf 配置中(
config/autoload/logger.php)确保default通道写入runtime/logs/task.log等明确路径 - 避免在
command末尾加> /dev/null 2>&1,这会丢弃全部标准流
显式声明环境变量与用户权限
定时任务常依赖特定环境(如 APP_ENV=prod、REDIS_HOST),Supervisor 不继承 shell 环境变量,必须显式注入;同时推荐以非 root 用户运行,降低安全风险。
-
environment=APP_ENV="prod",REDIS_HOST="127.0.0.1",REDIS_PORT="6379":键值对用英文逗号分隔,值加英文双引号 -
user=www-data或user=hyperf:提前创建对应用户,并确保其对项目目录有读写权限(特别是runtime/) - 若需监听 80/443 端口,可用
setuid或反向代理,不建议直接用 root










