Php 将SQS与多个Laravel队列读取器一起使用时出错
我使用Laravel作业从SQS队列读取消息(Laravel版本5.7) 在Laravel之后,我使用supervisor同时运行多个Php 将SQS与多个Laravel队列读取器一起使用时出错,php,laravel,amazon-sqs,Php,Laravel,Amazon Sqs,我使用Laravel作业从SQS队列读取消息(Laravel版本5.7) 在Laravel之后,我使用supervisor同时运行多个队列:工作进程 在我得到与消息可用性相关的SQS错误之前,一切进展顺利: InvalidParameterValue (client): Value ... for parameter ReceiptHandle is invalid. Reason: Message does not exist or is not available for visibil
队列:工作进程
在我得到与消息可用性相关的SQS错误之前,一切进展顺利:
InvalidParameterValue (client): Value
... for parameter ReceiptHandle is invalid. Reason: Message does not exist or
is not available for visibility timeout change. - <?xml version="1.0"?>
<ErrorResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/"><Error>
<Type>Sender</Type><Code>InvalidParameterValue</Code><Message>Value ...
for parameter ReceiptHandle is invalid. Reason: Message does not exist or is
not available for visibility timeout change.</Message><Detail/></Error>
<RequestId>8c1d28b7-a02c-5059-8b65-7c6292a0e56e</RequestId></ErrorResponse>
{"exception":"[object] (Aws\\Sqs\\Exception\\SqsException(code: 0): Error
executing \"ChangeMessageVisibility\" on \"https://sqs.eu-central-
1.amazonaws.com/123123123123/myQueue\"; AWS HTTP error: Client error: `POST
https://sqs.eu-central-1.amazonaws.com/123123123123/myQueue` resulted in a
`400 Bad Request` response:
尤其奇怪的是,消息不存在或不可用于可见性超时更改。
每个主管进程调用command=php/home/application/artisan queue:work
而不使用--sleep=3
(我希望进程是被动的,如果队列中没有任何内容,就不要等待3秒钟)或--trys=3
(我需要完成所有任务,因此我不限制trys
参数)
如果消息不存在(我不能排除这种可能性)为什么进程会从队列中获取它?我能做些什么来防止它呢?我也在生产中间歇性地看到这个错误,我们为一个SQS队列运行了大量的使用者。在我们的例子中,我非常确信错误是由于SQS的传递语义造成的。本质上,一条消息可以传递两次或者在罕见的情况下更多
Laravel的queue worker命令不是严格幂等的,因为它在尝试释放或删除不再可用的SQS消息时会引发异常(即,因为它已被另一个队列工作进程删除,该进程从SQS接收到消息的副本)
我们的解决方法是尝试检测何时接收到重复消息,然后尝试将消息安全释放回队列。如果当前处理该消息的另一个队列工作程序成功,它将删除该消息,并且不会再次接收该消息。如果另一个队列工作程序失败,则该消息将被释放后来又收到了类似这样的信息: