【发布时间】:2017-02-13 21:32:23
【问题描述】:
我们使用 Laravel Redis 队列和具有多个并行运行工作人员的主管设置。有时,队列中的一个元素会被多次处理。
有没有什么技巧,比如我可以设置一个标志或其他什么来避免这种行为?
【问题讨论】:
标签: php laravel supervisord
我们使用 Laravel Redis 队列和具有多个并行运行工作人员的主管设置。有时,队列中的一个元素会被多次处理。
有没有什么技巧,比如我可以设置一个标志或其他什么来避免这种行为?
【问题讨论】:
标签: php laravel supervisord
如果出现异常或作业莫名失败,作业将自动重试。即使大部分作业已经运行,也会发生这种情况。
【讨论】:
这是因为作业消息可供其他消费者使用。
在你的 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 秒后再次看到并提取消息。
【讨论】: