Heroku无需专用dyno能否稳定运行Laravel项目队列?
问题根因
你手动在Heroku控制台执行php artisan queue:work启动的是一次性临时dyno(one-off dyno),这类dyno的运行限制直接导致了进程中断:
- 无网络流量/空闲状态下30分钟就会被Heroku自动回收
- 即使一直有任务处理,最长运行时长也不会超过24小时
- 每次项目部署、dyno自动重启时,所有临时dyno都会被直接销毁,进程自然中断
低成本稳定运行方案
不想单独开通付费worker dyno的话,可以根据你的业务量级选择对应的方案:
- 方案1:把队列进程合并到web dyno中,修改你的
Procfile为以下内容:
该方案适合小流量、队列任务少的场景,hobby dyno标配512M内存,只要web服务+队列进程的总内存占用不超过上限就能稳定运行,部署后自动启动无需手动操作。如果偶尔出现内存溢出被系统kill,Heroku会自动重启整个web dyno,队列进程也会同步恢复。web: vendor/bin/heroku-php-apache2 public/ & php artisan queue:work database --tries=3
补充说明:hobby dyno默认30分钟无web请求就会进入休眠,队列进程也会同步停止,你可以通过定时健康检测的方式,每5分钟请求一次你的站点域名,就能保持dyno持续运行。 - 方案2:改用同步队列驱动,直接在
.env文件中将QUEUE_CONNECTION改为sync,不需要单独运行队列进程,任务会在请求触发时同步执行,完全没有额外进程开销,缺点是发邮件的请求响应会变慢,适合每日邮件发送量不超过数百的场景。 - 方案3:通过调度器触发队列处理,在
app/Console/Kernel.php中添加定时任务,每分钟执行一次php artisan queue:work --stop-when-empty,再安装Heroku官方免费的调度器插件触发Laravel调度即可,不需要常驻进程,每次有任务就处理完自动退出,不会占用额外常驻内存。
如果你的队列任务量每日超过一千,或者存在大耗时的队列任务,还是建议单独开通worker dyno,避免队列进程占用资源影响web服务的响应速度。
同场景使用情况
大量使用Heroku hobby plan搭建个人项目、小流量商业项目的开发者都会采用上述合并进程/同步队列/定时触发队列的方案,避免额外支付worker dyno的费用,只要队列任务量级不大,这类方案的稳定性完全可以满足需求。
内容的提问来源于stack exchange,提问作者Dom
相关产品推荐
相关产品推荐

