Php 将SQS与多个Laravel队列读取器一起使用时出错

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

我使用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 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接收到消息的副本)

我们的解决方法是尝试检测何时接收到重复消息,然后尝试将消息安全释放回队列。如果当前处理该消息的另一个队列工作程序成功,它将删除该消息,并且不会再次接收该消息。如果另一个队列工作程序失败,则该消息将被释放后来又收到了类似这样的信息: