marchie/laravel-queue-azure-restarter

当Laravel队列工人在Azure上失败时重新启动

dev-master 2015-11-13 09:30 UTC

This package is not auto-updated.

Last update: 2024-09-14 18:26:00 UTC


README

这个包是用来做什么的?

TL;DR:我的队列守护进程在几天后变成了僵尸,这个包可以杀死僵尸

我使用一个队列守护进程来处理我的Laravel应用程序中的任务,例如发送电子邮件。守护进程已设置为Azure上的持续Web作业,因此如果它崩溃,Azure会立即将其重新启动(这与*nix上的Supervisord提供的功能相同)。然而,守护进程是一个长时间运行的过程,我发现有几个问题;例如,经过一段时间后,我会连接到外部邮件服务器时出现SSL错误。这些问题通过设置一个计划Web作业来定期执行php artisan queue:restart命令得到了解决;这有点像黑客行为,但它确实完成了工作。

所以,一切都很好...直到它不再好!一个可怕的发现等待我周一早上:一周的邮件都在队列中,等待处理。到底是怎么回事?!我检查了Azure上的队列守护进程,然后...它在运行?我进一步调查。在前一个周六凌晨某个时候,守护进程停止了对重启命令的响应,它就坐在那里,闲置。进程没有停止,所以Azure不知道它需要重启,但它什么也没做。进程有脉搏,但没有大脑活动。

我在网上搜索了一番;是否还有其他人见过这种情况?事实证明,这种情况并不常见,但也不是前所未有的(例如,laravel/framework#4443)。进一步搜索表明,这可能与PHP的sleep()函数本身有关。

因此,我需要一种方法来检查队列守护进程不仅仍在运行,而且还在正常工作。然后,如果守护进程变成了僵尸,队列需要自动重启(我喜欢我的周末属于我自己!)。

幸运的是,解决方案在于Azure的Kudu API。 该API允许我们获取服务器上运行的过程信息,并且更重要的是,可以终止它们!

因此,这个包就诞生了!

Laravel安装和配置

将以下内容添加到应用程序的composer.json文件中的require部分

"marchie\laravel-queue-azure-restarter": "dev-master"

运行composer update以安装包。

现在,将服务提供者添加到Laravel的config/app.php文件中的providers数组中

Marchie\LaravelQueueAzureRestarter\ServiceProvider::class

现在,需要配置包。以下键和值需要添加到应用程序的.env文件中

  • KUDU_USER 访问Kudu API的用户名
  • KUDU_PASS 访问Kudu API的密码
  • AZURE_INSTANCE 您的Azure实例名称;例如 https://[instance].scm.azurewebsites.net
  • QUEUE_FAIL_TIMEOUT 队列超时需要经过的时间,例如 20分钟1小时等。

(有关Kudu凭据的更多信息)

或者,您可以使用php artisan vendor:publish命令发布配置,并在config/laravel-queue-azure-restarter.php文件中编辑值。

您可以使用php artisan kudu:test测试您的应用程序是否可以连接到Kudu。

那么,Laravel部分就完成了...

Azure配置

我们需要配置两个计划任务Web作业。第一个将作业推送到队列,用于在Laravel的缓存中设置当前的时间戳值。第二个作业将读取这个时间戳值并检查经过的时间。如果经过的时间超过了配置中设置的QUEUE_FAIL_TIMEOUT值,那么将通过Kudu API杀死队列守护进程。由于你已经将队列守护进程配置为持续运行的Web作业,Azure会看到它已经停止,并自动重启它!

第一个Web作业:queue:flag

第一个Web作业需要执行以下命令

php artisan queue:flag --queue=[QUEUE] <connection>

参数<connection>指定队列使用的驱动;默认值是你在Laravel的config/queue.php文件中设置的值。

选项--queue=[QUEUE]指定队列的名称;如果你没有使用命名队列,则默认为null

该Web作业将一个作业推送到队列,然后设置包含当前时间戳的值。

该Web作业需要比我们配置中的QUEUE_FAIL_TIMEOUT值更频繁地执行;例如,如果你的QUEUE_FAIL_TIMEOUT值是'20分钟',则Web作业必须每19分钟或更短的时间执行一次。

第二个Web作业:queue:check

第二个Web作业需要执行以下命令

php artisan queue:check --queue=[QUEUE] <connection>

参数<connection>指定队列使用的驱动;默认值是你在Laravel的config/queue.php文件中设置的值。

选项--queue=[QUEUE]指定队列的名称;如果你没有使用命名队列,则默认为null

Web作业可以按照你的需求频繁执行。该命令读取由queue:flag命令存储在缓存中的时间戳值,并计算出经过的时间。如果经过的时间超过了QUEUE_FAIL_TIMEOUT值,将通过Kudu API查找并终止僵尸队列守护进程。

关于失败的一则说明

当队列守护进程失败并终止进程时,包会抛出UnresponsiveQueueWorkerException异常。根据你的应用程序如何处理异常,这可以用于记录队列守护进程失败的事件,通知管理员等。

问题

cURL错误60:SSL证书问题:无法获取本地颁发机构证书

Azure Web应用默认没有设置证书包,因此你需要设置它才能访问Kudu API。你可以在http://blogs.msdn.com/b/azureossds/archive/2015/06/12/verify-peer-certificate-from-php-curl-for-azure-apps.aspx上找到如何操作。