Laravel 运行多个计划任务

Posted

技术标签:

【中文标题】Laravel 运行多个计划任务【英文标题】:Laravel run multiple scheduled tasks 【发布时间】:2016-06-24 17:20:28 【问题描述】:

我目前有一个计划的控制台命令,它每 5 分钟运行一次,没有重叠,如下所示:

 $schedule->command('crawler')
             ->everyFiveMinutes()
             ->withoutOverlapping()
             ->sendOutputTo('../_laravel/storage/logs/scheduler-log.txt');

所以效果很好,但我目前有大约 220 个页面,大约需要 3 小时才能完成,增量为 5 分钟,因为我只是强制它以每个间隔抓取 10 个页面,因为每个页面需要 20-30 秒来抓取由于各种因素。每个页面都是数据库中的一条记录。如果我最终要抓取 10,000 个页面,则此方法将不起作用,因为它需要超过 24 小时,并且每个页面应该每天重新抓取一次。

所以我的供应商最多允许 10 个并发请求(或更多,更高的计划),那么并发运行它的最佳方式是什么?如果我只是复制调度程序代码,如果我复制 10 次,它是否会运行相同的命令两次或类似 10 次?会导致什么问题?

然后我需要将参数传递给控制台,例如 1、2、3 等……我可以使用这些参数来确定要抓取哪些页面?即 1 表示 1-10 条记录,2 表示接下来的 11-20 条记录,依此类推。

使用这个StackOverfow 答案,我想我知道如何传递它,像这样:

 $schedule->command('crawler --sequence=1')

但是如何在Command 类中读取该参数?它只是成为一个普通的 php 变量,即$sequence

【问题讨论】:

你可以发布你的命令类吗?它从哪些类扩展而来? 大概有 500 行长,所以可能不应该在这里粘贴整个内容。它扩展了Command 类。 您打算如何运行多个队列侦听器并跨作业分块您的页面? 【参考方案1】:
    最好使用队列进行作业处理 在 cron 上,将所有作业添加到队列中 运行多个队列工作器,它们将并行处理作业

提示:它发生在我们身上。 可能会发生之前添加的作业未完成,但 cron 再次将相同的任务添加到队列中。由于队列按顺序工作。为了避免这种情况,您应该在数据库中标记上次任务完成的时间,以便您知道何时执行该作业(如果它被严重延迟)

【讨论】:

但是我怎么会有重复的队列呢?我使用任务调度程序的原因是我可以让它每 5 分钟运行一次,并检查是否需要重新抓取任何页面。有时没有,有时可能是 200 个。 我让你使用 cron 来确定哪些页面需要爬取。然后将这些页面添加为队列中的作业。现在正在运行的队列工作者将从队列中挑选作业,并一一爬行。 (如果您有 5 个工作人员在运行,一次将抓取 5 个页面)重复队列是什么意思? 我明白了。 Laravel 中的任务调度器基本上就是一个 cron 本身。所以你说我应该继续使用任务调度程序,除了检查哪些页面需要被爬取,然后将它们传递给队列来处理实际的爬取过程?我会在队列中阅读更多内容,以确保他们能够满足我的需求…… @zen 是的,这正是 Shyam 所说的——只要过程的“检查”部分快速简单(您甚至可以在几秒钟内检查这些未来的 10000 页)然后计划的命令应该每 5 分钟检查一次,并将需要“刷新”的任何页面添加到队列中。然后,您的 5 或 10 个队列工作人员将能够并行运行这些刷新操作。当队列上没有任何东西时,它们会“休眠”,因此开销很小,如果队列中有很多东西,它们将一次处理一个(乘以您拥有的工人数量)。 为此,您需要研究可用于运行命令并在它们死亡时/当它们死亡时使它们保持活力的实用程序。目前的首选工具是Supervisor。 FWIW 我最近才第一次在 Laravel 中使用队列,体验不是很好,因为有多种运行它们的方法。最后,我认为发现队列工作者(设置为守护程序模式 - 这与我可能添加的真正 Linux 守护程序不同)使用 Supervisor 保持“活动”对我来说是最好的。【参考方案2】:

我在文档中找到了这个,我希望这就是你要找的:

检索输入

当您的命令正在执行时,您显然需要访问 应用程序接受的参数和选项的值。到 这样做,您可以使用参数和选项方法:

检索命令参数的值

$value = $this->argument('name');

检索所有参数

$arguments = $this->argument();

检索命令的值 选项

$value = $this->option('name');

检索所有选项

$options = $this->option();

source

【讨论】:

谢谢。我想我会试试排队,因为这似乎是一个更好的选择,但我会把它放在我的后兜里以防万一。

以上是关于Laravel 运行多个计划任务的主要内容,如果未能解决你的问题,请参考以下文章

雪花任务多个计划

Laravel 计划任务(任务调度)的使用

Laravel 计划任务(任务调度)的使用

Laravel-任务调度

laravel 任务调度-即定时任务使用

[ Laravel 5.6 文档 ] 进阶系列 —— 任务调度