Laravel 完成后重新开始的工作?

Laravel 完成后重新开始的工作?,laravel,laravel-5,cron,queue,laravel-5.2,Laravel,Laravel 5,Cron,Queue,Laravel 5.2,我试图创建的是一个从十几个外部网站读取/解析数据的系统 例如,假设我想创建一个系统,解析特定用户个人资料页面上的Twitter帖子。我想为十几个用户做这个 此外,我希望为每个用户运行一个单独的作业。因此,如果有12个用户,我需要运行12个作业 当作业完成时(即,当它解析了页面上用户的所有帖子时),我需要重新开始作业(以便解析任何新帖子) 因此,最后,如果有12个用户,我应该有12个作业不断运行,解析这12个用户中任何一个的任何新帖子 据我所知,有两种方法可以做到这一点。第一种是使用,第二种是使用

我试图创建的是一个从十几个外部网站读取/解析数据的系统

例如,假设我想创建一个系统,解析特定用户个人资料页面上的Twitter帖子。我想为十几个用户做这个

此外,我希望为每个用户运行一个单独的作业。因此,如果有12个用户,我需要运行12个作业

当作业完成时(即,当它解析了页面上用户的所有帖子时),我需要重新开始作业(以便解析任何新帖子)

因此,最后,如果有12个用户,我应该有12个作业不断运行,解析这12个用户中任何一个的任何新帖子

据我所知,有两种方法可以做到这一点。第一种是使用,第二种是使用拉威尔的

解决这个问题的最佳方法是什么?Cron作业还是队列?我将如何正确实施它?

对于cron作业,我能想到的两个问题是cron基于时间运行,而不是基于作业完成,这意味着如果作业完成,它将不得不等待直到再次调用cron作业(例如,每5分钟一次)。另一个问题是重叠。如果某个作业没有及时完成,但cron再次调用该作业,该怎么办

这就是我当前队列作业实现的简化版本,然而,我注意到我的CPU使用率跳到了75-90%之间:

<?php

namespace App\Jobs;

use App\Jobs\Job;
use Illuminate\Contracts\Mail\Mailer;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

use App\Models\Page;

class PageParser extends Job implements ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    protected $page;

    public function __construct(Page $page)
    {
        $this->page = $page;
    }

    public function handle()
    {
        // Parsing done here, removed for simplicity

        $this->delete();
        dispatch(new PageParser($this->page));
    }
}

我没有尝试过这个,但我假设您可以创建一个递归作业

这个递归作业将执行它需要执行的所有代码,然后在执行结束时,它将创建一个新作业并将其推送到队列上——队列准备就绪后,队列将立即开始运行


如果作业在任何时候失败,您都不会创建新作业,因此不会同时运行同一用户的任何作业。失败的作业将被重试—成功后,将创建一个新作业。

我没有尝试过此操作,但我假设您可以创建一个递归作业

这个递归作业将执行它需要执行的所有代码,然后在执行结束时,它将创建一个新作业并将其推送到队列上——队列准备就绪后,队列将立即开始运行


如果作业在任何时候失败,您都不会创建新作业,因此不会同时运行同一用户的任何作业。失败的作业将被重试,成功后将创建一个新作业。

您可以使用组合。创建类似“RetrieveDataCommand”之类的命令。此命令应将每个用户的作业推送到队列中,队列将检索该用户的数据(如果需要,可能还有一个单独的作业用于实际处理?)。作业应考虑“$from”参数,如果在运行“previous”命令时,该参数是时间戳。当它运行时,它检索$from to now()时间段内所有用户的所有数据

然后,您可以让cron作业每隔10秒或任何时间运行一次该命令。$from可以通过在cron运行命令后立即存储(在缓存/DB/something半持久性中)当前时间的时间戳来计算,以便下一个命令可以在运行时查找它,然后在下一次运行时覆盖它。或者简单地执行donow()减去cron间隔,尽管这不太灵活


然后,您可以从作业中删除自删除和分派内容

您可以使用组合。创建类似“RetrieveDataCommand”之类的命令。此命令应将每个用户的作业推送到队列中,队列将检索该用户的数据(如果需要,可能还有一个单独的作业用于实际处理?)。作业应考虑“$from”参数,如果在运行“previous”命令时,该参数是时间戳。当它运行时,它检索$from to now()时间段内所有用户的所有数据

然后,您可以让cron作业每隔10秒或任何时间运行一次该命令。$from可以通过在cron运行命令后立即存储(在缓存/DB/something半持久性中)当前时间的时间戳来计算,以便下一个命令可以在运行时查找它,然后在下一次运行时覆盖它。或者简单地执行donow()减去cron间隔,尽管这不太灵活


然后你可以从你的工作中删除自我删除和发送的内容

你真的在寻找Twitter帖子吗?如果是这样,你应该看看他们的流媒体端点。根据连接状态使用while循环创建一个永无止境的工作是非常容易的。不,我不是在寻找Twitter帖子。我的例子是对总体思路的简化。你真的在寻找Twitter帖子吗?如果是这样,你应该看看他们的流媒体端点。根据连接状态使用while循环创建一个永无止境的工作是非常容易的。不,我不是在寻找Twitter帖子。我的例子是对一般想法的简化。