2017-07-07 39 views
2

我在网上搜索,但我没有找到任何解决方案,我的问题。 我使用laravel 5.2和SQS作为队列驱动程序。 我正在派遣一份工作,以便将电子邮件发送给100位用户。 作业收到“文章”模型和“用户”数组,并且每个用户都应该收到带有“文章”的电子邮件。Laravel工作大小限制已超过256kb(队列SQS aws)

当它是10个用户都可以。 当它是100个用户时,我收到来自amazon SQS服务的错误消息“400错误请求”,并且响应是:“原因:消息必须小于262144字节。” 我明白这个工作的要求太大,因为用户的数组。

我想拆分用户的数组,以便将作业的请求大小减少到小于256kb。 我可以通过循环遍历用户的数组来完成,每当我接近256kb时,我将派发一篇文章和用户的工作,然后我将继续运行数组中的其余用户。

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

非常感谢您提前 狮子座。

+0

有你派遣一个工作有100篇文章,而不是100个工作岗位的理由每篇有1篇文章?这首先是队列系统的一大特点。 – CmdrSharp

+0

@CmdrSharp我正在发送一个包含100个项目的作业(1个EVENT和100个用户),以减少队列请求。每个EVENT将运行在用户身上,并将发送EMAIL到100个用户的相同(取决于条件),因此最终我将发送100个作业发送EMAIL。 SO 1 EVENT工作,100个用户和100个工作岗位发送EMAILS。 – llioor

回答

1

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

因为SerializesModels的特质作业使用,雄辩 车型将正常序列化,序列化时,工作是 处理。如果您的排队作业在其构造函数 中接受了Eloquent模型,则只有模型的标识符将被序列化到队列中的 。

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

1

好的,您已经知道SerializesModels trait通过保存模型类和id,有助于保持有效负载的低,以便在作业解析时从数据库中再次获取。

如果它仍然使作业过大,队列对象是在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. 
+0

我不明白如何检查“serialize($ this)”的大小,我怎么知道在我派遣工作之前什么时候达到256kb的限制?谢谢! – llioor

+0

嘿@alepeino strlen()不会返回“大小”,而是“长度”。对我来说,这仍然不是正确的答案。现在我通过将用户数组拆分为100个组来解决这个问题,如果我拥有100,000个用户,则作业大小不会超过256kb,但我有1000个作业。主要问题是如何检查请求的大小,然后我可以优化队列中的作业数量。 – llioor

+0

@llioor等待,但不是作业的大小(主要是)它的有效载荷的大小,你得到的序列化?我在这里错过了什么? – alepeino