根据 php 脚本中的作业订单安排 cron 作业的更好方法

Better way to schedule cron jobs based on job orders from php script

所以我用 NodeJS 编写了简单的视频创建脚本。

计划的 cron 作业 运行。

我有一个用 PHP 编写的面板,用户输入详细信息并单击“提交新视频作业”按钮。 这个新工作正在保存到数据库,其中包含 详细信息、jobId 和 status="waiting" 数据。

PHP API负责一次返回1个状态,检查status="waiting" 将查询限制为 1 然后 returns data with jobID when asked

视频创建脚本每 x 秒请求一次 API 请求新工作可用。

它有 5 个任务。

可用=真。

  1. 检查是否有新工作订单(每20秒有GET请求),如果有新工作; 可用=假
  2. 获取详细信息(姓名、图片url等)
  3. 创建包含详细信息的视频。
  4. 将视频上传到 FTP
  5. Post 数据到 API 以更新详细信息。并将该工作标记为“完成”

可用=真;

这些任务是异步的,因此每个任务都必须等待上一个任务完成。

现在,获取或 post 请求 api 如果每 20 秒有新工作(时间无关紧要) 对我来说似乎是个坏方法。

那么有什么方法/包/系统可以完成这个行为吗?

代码示例:

const cron = require('node-cron');
let available=true;

var scheduler = cron.schedule(
    '*/20 * * * * *',
    () => {
        if (available) {
            makevideo();
        }
    },
    {
        scheduled: false,
        timezone: 'Europe/Istanbul',
    }
);


let makevideo = async () => {
    available = false;
    let {data} = await axios.get(
        'https://api/checkJob'
    );
    if (data == 0) {
        console.log('No Job');
        available = true;
    } else {
        let jobid = data.id;
    await createvideo();
    await sendToFTP();
    
        await axios.post('https://api/saveJob', {
            id: jobid,
            videoPath: 'somevideopath',
        });
        available = true;
    }
};
scheduler.start();

您在非常标准的系统设计范例中使用 Apache Kafka 或任何基于队列的实现(例如 RabbitMQ)完成的工作。您可以查看 Kafka/rabbitmq 但基本上不会详细介绍:

  1. 有一个中央队列。
  2. 当用户提交作业时,作业会添加到队列中。
  3. 视频处理器会无限期地运行以订阅队列。

你可以继续往下看:https://www.gentlydownthe.stream/你会发现你所做的事情的相似之处。

这里不需要自己poll,需要订阅一个事件,其他的事情由各自的队列管理。

虽然可以将数据库用作队列,但它通常被称为反模式(仅次于使用数据库进行日志记录),正如您正在寻找的那样:

So any way / package / system to accomplish this behavior?

由于悬赏建议,我使用了你问题的自由形式:Beanstalk

Beanstalk is a simple, fast work queue.

Its interface is generic, but was originally designed for reducing the latency of page views in high-volume web applications by running time-consuming tasks asynchronously.

它具有您在问题中提到的语言(以及更多)的客户端库,易于开发并 运行 在生产中使用。

RabbitMQ 也是一个很好的队列系统。

为什么?

它确实有很好的文档记录(许多语言的示例,包括 javascript 和 php)。

Tutorials 在公开真实用例时很简单。

它有一个 REST API。

它附带一个监控 UI。


如何使用它来解决您的问题?

在作业生产者端:按照 tutorial 1

将消息(作业)发送到队列

要使用 nodejs 进程使用作业:请参阅 RabbitMQ 的 tutorial 2


其他建议:

使用预取值 1 并由发布者确认,这样您就可以确保消费者实例不会在有作业时接收消息 运行。

快速原型路线图:教程 1...然后是教程 2 x)。发送和接收消息后,您可以探索可以在队列和消息上设置的选项

Nodejs 包:http://www.squaremobius.net/amqp.node/

PHP 包裹:https://github.com/php-amqplib/php-amqplib