incapption/load-balanced-cron-task

根据单个远程MySQL数据库将cron作业分配到相同的web服务器。

2.0.0 2022-05-17 14:53 UTC

This package is auto-updated.

Last update: 2024-09-22 06:40:38 UTC


README

简介

这是一个用于负载均衡cron任务的轻量级软件包。它用于在服务器网络中分配任务,以确保任务只运行一次而不是多次。

重要的是,您的应用程序网络只能使用一个中央MySQL数据库。在数据库中创建一个表,用于插入当前任务。主键确保任务只运行一次(一种锁定过程)。

“unique_hash”是任务名称、计划和当前时间戳(不含秒)的MD5哈希值。这样,节点可以异步运行,但任务一次只运行一次。

操作方案

alt text

需求

  • 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