繁体   English   中英

Laravel作业大小限制已超过256kb(队列SQS aws)

[英]Laravel job size limit is been exceeded 256kb (queue SQS aws)

我在网上搜索但我没有找到任何解决方案。 我正在使用带有SQS的laravel 5.2作为队列驱动程序。 我正在派遣一份工作,以便向100位用户发送电子邮件。 该作业接收“文章”模型和“用户”数组,并且每个用户都应该收到带有“文章”的电子邮件。

当它是10个用户时一切都OK。 当它是100个用户时,我从amazon SQS服务收到错误消息“400 bad request”,响应是:“原因:消息必须短于262144字节。” 我知道由于用户的数组,作业的请求太大了。

我想拆分用户的数组,以便将作业的请求大小减少到256kb以下。 我可以通过循环访问用户的数组来完成它,每当我达到接近256kb时,我将使用文章和用户调度作业,然后我将继续运行数组中的其余用户。

  1. 在我们发送之前检查当前作业请求大小的方法是什么?
  2. 您有更好的解决方案吗?

非常感谢Leo。

我找到了解决问题的方法。 答案写在文档中:

由于作业正在使用的SerializesModels特性,当作业处理时,Eloquent模型将被优雅地序列化和反序列化。 如果排队作业在其构造函数中接受Eloquent模型,则只有模型的标识符将序列化到队列中。

这意味着laravel只保存序列化雄辩模型的ID。 像这样我们减少了调度作业的大小。 另一方面,在发送作业之前,我仍然不知道如何检查作业的大小。

编辑+解决方案:

基本上处理它的最好方法是派遣许多工作。 我将用一个例子来解释。 假设我们在工作中有一个事件,我们想要通知所有工人。 处理它的最好方法是使用event-> id调度一个作业(排队),然后在该作业内部循环工作者并使用$ worker-> id分派许多作业(队列)。 像这样,队列大小永远不会太大。 如果我们将为所有工作人员派遣一份工作,我可以达到1000s ids(工人ID),并且像这样我们将达到队列限制大小。

希望很清楚。 利奥尔。

好的,您已经发现SerializesModels特性通过保存模型类和ID来帮助保持较低的有效负载大小,以便在作业解析时从数据库中再次获取。

如果仍然使作业太大,则Queue对象是在createObjectPayload方法中创建有效内容的对象。 它受到保护,因此您可能无法从外部轻松访问它,但大多数有效负载只是serialize(clone $job) 这将使您了解当前工作的大小。 也许在作业类中创建一个方法,将用户添加到其内部Eloquent \\ Collection,直到serialize($this)达到限制?


如果作业构造函数是

public function __construct(\Illuminate\Database\Eloquent\Collection $users, $maxSize)
{
    $this->users = new \Illuminate\Database\Eloquent\Collection();

    while (strlen(serialize(clone $this)) < $maxSize) {
        $this->users->push($users->shift());
    }
}

然后你这样称呼它:

// $usersToNotify is the collection with the users

$job = new YourJob($usersToNotify, $maxSize);

// Now the job has all users within the limit,
// and $usersToNotify has the remaining users.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM