我有一个在Elastic Beanstalk上运行的工作程序,该工作程序通过来自队列的消息接受POST请求。这些消息会触发耗时数分钟(有时甚至数小时)的长时间操作,并且至关重要的是此操作只能执行一次。
问题是,当我登录到工作人员控制台以查看该过程时,该消息似乎一遍又一遍地传递(通过接收请求触发的方法每分钟都会调用一次)。我如何摆脱这种行为?
我阅读了文档,并将服务队列和死信队列的可见超时时间设置为最大值(12小时)。但是,这完全没有帮助。
当我发送消息时,它显示为“飞行中”(我认为这是一种假定的行为,因为队列等待接收删除请求或仅在长时间操作结束时提供的某种答案) 。
有人可以提示我这种情况下发生了什么吗?我可能错过了配置中的一些重要细节...
编辑:似乎消息每分钟都在重新传送,只要它在“飞行中”即可。一旦完成此过程,该消息最终消失。
这里有一层额外的复杂性,因为您不是直接轮询SQS队列。Elastic Beanstalk部署了一个工作进程,该工作进程sqsd
代表您轮询队列,将其到达应用程序的所有消息发布到POST,并在响应为200时将其从队列中删除。
队列上的VisibilityTimeout设置控制在将消息传递给使用者(在本例中为sqsd)之前,假设该队列出了点问题并将该消息重新传递给其他人之前,队列等待多长时间。sqsd也有类似的概念(称为“InactivityTimeout”)是多长时间控制它它假定了毛病和重试前发布后,等待您的应用程序。您需要将其配置为足够高,以使sqsd在完成处理之前不会将请求重新发送到您的应用程序。我看到了另一个“ ProxyTimeout”设置的报告,该设置可能也需要进行调整。
更普遍地说,请记住,在分布式系统中,实际上不可能一次保证完全交付-即使您正确地设置了所有超时时间,因此在大多数情况下都能正常工作,但总有可能在崩溃后崩溃完成该操作,但在您将其告知SQS之前,该消息将重新发送给其他人。您可以得到的最接近的结果是,如果两次发送邮件,则确保结果完全相同-例如,通过让您的处理逻辑检查要执行的操作是否已经完成,以及是否已经完成立即返回200。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句