【问题标题】:Heroku workers crashing in laravel app if number of workers > 1如果工人数量 > 1,Heroku 工人在 laravel 应用程序中崩溃
【发布时间】:2021-03-18 07:41:57
【问题描述】:

多年来,我一直在使用 Heroku 托管我的应用程序,但刚刚开始遇到工作队列积压的问题。我希望我可以通过增加运行的工作人员数量来解决这个问题,以便可以并行完成排队的作业,但是每当我增加工作人员的数量时,除了一次崩溃之外都没有。

这是我的 Procfile:

web: vendor/bin/heroku-php-apache2 public
worker: php /app/artisan queue:restart && php /app/artisan queue:work redis --tries=3 --timeout=30

当我将工作人员扩展到大于 1 的任何值时,这是我的服务器日志的输出(在此示例中,它只是将其扩展到 2 个工作人员):

    Mar 16 06:04:51 heroku/worker.1 Starting process with command `php /app/artisan queue:restart && php /app/artisan queue:work redis --tries=3 --timeout=30`
    Mar 16 06:04:52 heroku/worker.1 State changed from starting to up
    Mar 16 06:04:54 app/worker.1 Broadcasting queue restart signal.
    Mar 16 06:04:58 heroku/worker.2 Process exited with status 0
    Mar 16 06:04:58 heroku/worker.2 State changed from up to crashed
    Mar 16 06:04:58 heroku/worker.2 State changed from crashed to starting
    Mar 16 06:05:09 heroku/worker.2 Starting process with command `php /app/artisan queue:restart && php /app/artisan queue:work redis --tries=3 --timeout=30`
    Mar 16 06:05:10 heroku/worker.2 State changed from starting to up
    Mar 16 06:05:14 app/worker.2 Broadcasting queue restart signal.
    Mar 16 06:05:19 heroku/worker.1 Process exited with status 0
    Mar 16 06:05:19 heroku/worker.1 State changed from up to crashed

如您所见,两个工作人员都尝试启动,但只有 worker.2 保持启动状态。

崩溃的工作人员每 10 分钟尝试重新启动一次,结果与上述相同。

当我运行heroku ps 时,我看到的是:

    === worker (Standard-1X): php /app/artisan queue:restart && php /app/artisan queue:work redis --tries=3 --timeout=30 (2)
    worker.1: crashed 2021/03/16 06:05:19 -0600 (~ 20m ago)
    worker.2: up 2021/03/16 06:05:10 -0600 (~ 20m ago)

(我的普通网络测功机可以放大和缩小,所以我没有在这里展示)。

对可能发生的事情有任何想法吗?我的第一个想法是 Heroku 出了问题,但我意识到事实并非如此。我的第二个想法是我的工人的 Procfile 条目可能会导致问题,但我对该条目的了解不够多,无法知道可能是什么原因。

同样,这对于 1 名工人来说已经工作了很长时间,并且只有当我尝试扩大到超过 1 名工人时才会发生崩溃。无论我尝试扩展到多少工作人员,只有一个不会崩溃并保持活跃并能够接收和处理作业。

其他信息:

  • Heroku 堆栈:Heroku-18
  • Laravel 版本:8.*
  • 队列驱动程序:Redis

更新 - 我在我的暂存环境中扩展了测功机,并且能够在没有任何崩溃的情况下上下扩展工作人员。现在我在想可能会有某种附加冲突或其他事情发生。如果我发现任何其他问题,我会更新此内容(已经联系 Heroku 支持)。

【问题讨论】:

标签: laravel heroku procfile


【解决方案1】:

问题出在 procfile 中的 php /app/artisan queue:restart 命令。正在启动的工人和被调用的重新启动命令导致了相互冲突的信号,并最终导致除了一个工人之外的所有工人崩溃。

我取消了那个命令,现在我可以毫无问题地扩展我的工人了。

=== worker (Standard-1X): php /app/artisan queue:work redis --queue=high,default,sync,emails,cron --tries=3 --timeout=30 (2)
worker.1: up 2021/03/17 17:29:32 -0600 (~ 8m ago)
worker.2: up 2021/03/17 17:35:58 -0600 (~ 2m ago)

当对 Heroku 进行部署时,dyno 会收到一个 SIGTERM 信号,该信号会杀死任何延迟的进程,然后重新启动 dyno。这意味着php /app/artisan queue:restart 命令是多余且不必要的。

主要的困惑在于 Laravel 在此处表述有关队列工作人员需要重启的信息的方式:https://laravel.com/docs/8.x/queues#queue-workers-and-deployment。这在没有像 Heroku 那样处理测功机的服务器上是必需的。

【讨论】:

  • 很好地发现了问题。 queue:restart 命令名称具有误导性——它所做的只是在缓存中设置一个标志,所有队列工作人员在开始新作业之前都会读取该标志。如果标志有新值,它们将退出并假设主管将重新启动它们。因此,当您扩大规模时,每次 heroku 添加一个新的测功机时,它也会杀死所有其他人。它确实会重新启动该过程,但有一个 backoff policy 使其不可靠。
猜你喜欢
  • 1970-01-01
  • 2018-07-09
  • 1970-01-01
  • 2013-08-09
  • 2013-12-24
  • 1970-01-01
  • 1970-01-01
  • 2019-02-06
  • 2011-10-03
相关资源
最近更新 更多