incapption / load-balanced-cron-task
根据单个远程MySQL数据库将cron作业分配到相同的web服务器。
2.0.0
2022-05-17 14:53 UTC
Requires
- php: >=7.2
- ext-json: *
- ext-pdo: *
- ext-pdo_mysql: *
- myclabs/php-enum: ^1.8
Requires (Dev)
- phpunit/phpunit: ^9.5
README
简介
这是一个用于负载均衡cron任务的轻量级软件包。它用于在服务器网络中分配任务,以确保任务只运行一次而不是多次。
重要的是,您的应用程序网络只能使用一个中央MySQL数据库。在数据库中创建一个表,用于插入当前任务。主键确保任务只运行一次(一种锁定过程)。
“unique_hash”是任务名称、计划和当前时间戳(不含秒)的MD5哈希值。这样,节点可以异步运行,但任务一次只运行一次。
操作方案
需求
- MySQL数据库
- PHP PDO扩展(ext-pdo,ext-pdo_mysql)
1. 安装
1.1 Composer
使用Composer安装Load Balanced Cron Task
。
$ composer require incapption/load-balanced-cron-task
1.2 创建MySQL表
此软件包需要在您的数据库中创建一个小表。它用于锁定正在运行的任务,确保只有一个应用程序实例可以运行它。
CREATE TABLE IF NOT EXISTS `lbct_tasks` ( `id` int(11) NOT NULL AUTO_INCREMENT, `unique_hash` varchar(32) NOT NULL, `task` varchar(256) NOT NULL, `schedule` varchar(256) NOT NULL, `date_created` datetime NOT NULL, `worker` varchar(256), PRIMARY KEY (`unique_hash`), KEY `id` (`id`) );
1.3 安装Crontab
思路是每分钟只有一个cron任务运行。这个cron任务包含所有其他由LoadBalancedCronTask
包装的任务。
打开您的cron表控制台(例如,Linux:crontab -e
)
* * * * /usr/bin/php /your/local/path/cron.php
1.4 创建您的cron文件
您可能希望将其集成到您的应用程序中,或者创建一个新的纯文件。
<?php use Incapption\LoadBalancedCronTask\Abstracts\CronTaskAbstract; use Incapption\LoadBalancedCronTask\LoadBalancedCronTask; use Incapption\LoadBalancedCronTask\Exceptions\LoadBalancedCronTaskException; require_once('./vendor/autoload.php'); class TestCronTask extends CronTaskAbstract { public function __construct() { $this->name = 'TestCronTask'; } public function task(): bool { // do your cron task return file_put_contents('test.html', 'awesome! it works! '.date('Y-m-d H:i:s', time())); } } try { $response = (new LoadBalancedCronTask()) ->mysql($_ENV['MYSQL_HOST'], $_ENV['MYSQL_USER'], $_ENV['MYSQL_PASSWORD'], $_ENV['MYSQL_DATABASE']) ->setWorkerName('Node 1') ->task((new TestCronTask())) ->loadBalanced() ->everyMinute() ->run(); } catch (LoadBalancedCronTaskException $e) { exit($e->getMessage()); }
2. 如何使用它
如上例所示,您需要为cron任务创建扩展CronTaskAbstract的类。在task()方法中定义行为。
然后创建负载均衡cron任务。
# Example for a distributed load balanced cron task $response = (new LoadBalancedCronTask()) ->mysql($_ENV['MYSQL_HOST'], $_ENV['MYSQL_USER'], $_ENV['MYSQL_PASSWORD'], $_ENV['MYSQL_DATABASE']) ->setWorkerName('Node 1') ->task((new TestCronTask())) ->loadBalanced() ->everyMinute() ->run(); # Example for a local cron task $response = (new LoadBalancedCronTask()) ->task((new TestCronTask())) ->local() ->everyMinute() ->run();
2.1 可链方法
通用
调度方法
如果您使用monthlyOn(),请注意月份的29日、30日、31日。可能需要使用lastDayOfMonth()或lastDayOfMonthOffset()代替。
3. 异常
LoadBalancedCronTask()
的实例在逻辑内部出现错误时抛出LoadBalancedCronTaskException
,对于其他所有情况,您都可以使用默认的PHP Exceptions
。