jdavidbakr / multi-server-event
此包扩展了Laravel的本地Command Event类,允许管理在同一系统上由多个服务器引发的事件,防止事件被多次触发
Requires
- php: >=5.5.9
- laravel/framework: >=5.4.26 <5.6
Requires (Dev)
- orchestra/testbench: ^3.4
- phpunit/phpunit: ~4.0||~5.0
README
此包扩展了Laravel的本地Event类,包括阻止事件在多个服务器之间发生的功能,例如在自动扩展情况下,负载均衡器后面的Laravel实例。
它使用数据库表来跟踪当前正在运行的过程,每个服务器生成一个唯一的密钥来锁定命令。为了防止短运行命令的锁定时间不够长的情况,我们正在实施命令完成和下一次执行时间之间的最小10秒间隔,因此如果命令每分钟运行一次,但完成时间在50到59秒之间,则下一次命令将延迟一分钟。
注意:Laravel 5.6现在包含一个名为 onOneServer()
的函数,该函数解决了此包旨在解决的问题。因此,建议您使用核心函数而不是此包。
对于Laravel < 5.4,请使用版本1.X
从版本1.X升级
如果从版本1.X升级,请注意在 app\Console\Kernel.php 中的 defineConsoleSchedule() 命令中的更改。
安装
$ composer require jdavidbakr/multi-server-event
新的事件结构使用数据库表来跟踪哪个服务器正在执行事件。您必须使用提供的迁移来创建数据库表。为此,将以下内容添加到 \App\Console\Kernel.php 中的 $commands 数组中
\jdavidbakr\MultiServerEvent\Commands\MultiServerMigrationService::class,
然后执行迁移
php artisan make:migration:multi-server-event
php artisan migrate
现在我们想要更改默认的调度IoC以使用此备用方案。在 app\Console\Kernel.php 中添加以下函数
/** * Define the application's command schedule. * * @return void */ protected function defineConsoleSchedule() { $this->app->instance( Schedule::class, $schedule = new \jdavidbakr\MultiServerEvent\Scheduling\Schedule() ); $this->schedule($schedule); }
用法
在编写您的调度时,只需将 "withoutOverlappingMultiServer()" 添加到命令中,例如
$schedule->command('inspire') ->daily() ->withoutOverlappingMultiServer();
这将防止多个服务器同时执行相同的事件。
在编写您的调度时,还可以确保cron不会卡住,只需将 "ensureFinishedMultiServer()" 添加到命令中,例如
$schedule->command('inspire') ->daily() ->withoutOverlappingMultiServer() ->ensureFinishedMultiServer(30);
这将防止在丢失连接或部署期间出现卡住的命令。注意,选择足够的时间以标记为“卡住”,例如,长时间运行的命令应该有更大的容忍时间。您可以通过绑定监听器在 EnsureCleanUpExecuted
事件上跟踪此类事件发生的频率。
测试
phpunit