我们使用Laravel Redis Queue和一个具有多个并行运行工作程序的管理程序设置。有时会发生队列中的一个元素多次处理。
是否有诀窍,比如我可以设置的标志或其他什么来避免这种行为?
答案 0 :(得分:2)
如果有异常或作业莫名其妙地失败,则会自动重试作业。即使大部分工作已经运行,也会发生这种情况。
答案 1 :(得分:1)
这是因为工作消息可供其他使用者使用。
在您的config / queue.php配置文件中,每个队列连接 定义一个retry_after选项。此选项指定多少秒 队列连接应等待,然后重试正在执行的作业 处理。例如,如果retry_after的值设置为90,则 如果已经处理了作业,则作业将被释放回到队列中 90秒未删除。通常,您应该设置 retry_after值是您的作业应合理花费的最大秒数,以完成处理。
请参见https://laravel.com/docs/5.7/queues#queue-workers-and-deployment
当使用者从队列接收并处理消息时,该消息将保留在队列中。队列不会自动删除邮件。由于队列是分布式系统,因此不能保证使用者实际上收到了消息(例如,由于连接问题或使用者应用程序中的问题)。因此,使用者必须在接收和处理消息后从队列中删除该消息。收到消息后,消息立即保留在队列中。为了防止其他使用者再次处理该消息,您应该将retry_after
值设置为您的作业完成处理所需的最大秒数。
对于Amazon SQS:
唯一不包含retry_after
值的队列连接是SQS。 SQS将根据在AWS控制台中管理的默认可见性超时重试作业。 Amazon SQS设置可见性超时,在这段时间内Amazon SQS阻止其他使用者接收和处理消息。邮件的默认可见性超时为30秒。这意味着其他使用者可以在30秒后再次看到并提取邮件。