4

我有一个应用程序从 SQS 读取消息(我们称之为队列“p”),进行计算量大的图像处理(步骤 #1),将结果上传到 S3 并从队列“p”中删除消息,然后发送一个通知到 SNS 主题(此 SNS 主题将消息路由到另一个名为“q”的队列)。还有另一个应用程序从队列“q”中读取并执行图像处理的第二阶段(从 S3 下载步骤 #1 的结果并对该结果执行额外的数学运算)。

我有运行第 1 步应用程序的常规实例 + 现货实例的组合。我知道(由于 SQS 可见性超时概念)如果现场实例在图像处理阶段关闭,SQS 会使消息再次对其他消费者可见,因此非现场 EC2 实例最终将完成现场的工作由于系统关闭,实例无法完成。

现在我的问题是:如果现场实例在删除之后但在消息发送到 SNS 之前完全关闭会发生什么?我们怎样才能从这样的事件中恢复过来?

# PSEUDO CODE
msg = read message from queue 
result = doWork(msg)
upload result to S3
delete msg 
publish to sns about result

干杯!

4

1 回答 1

7

首先,进程 A 不应该从其 SQS 队列中删除该消息,直到它发送 SNS 消息以启动第二个进程之后。从队列中删除消息是您应该做的最后一件事,以表明“我的工作已完成”。在发送 SNS 消息之前,工作尚未完成。

其次,在设计这样的过程时(尤其是在使用现场实例时)需要接受的关键事项之一是幂等性的概念:http ://en.wikipedia.org/wiki/Idempotence

一个一元运算(或函数)是幂等的,如果当它被两次应用于任何值时,它给出的结果就像它被应用一次一样

更多信息: http: //aws.amazon.com/sqs/faqs/#How_many_times_will_I_receive_each_message

Amazon SQS 旨在提供其队列中所有消息的“至少一次”传输。尽管大多数情况下每条消息将只传递给您的应用程序一次,但您应该设计您的系统,以便多次处理消息不会产生任何错误或不一致。

这最终意味着,无论现场实例是否在进程中关闭,SQS 队列中的给定消息都有可能同时传递到多个工作进程或多次传递到同一个进程,要么是因为 SQS 发送了两次,要么是在 SNS 消息发送后但在 SQS 队列更新之前点失败。

在不确切知道您的处理需要什么的情况下,我无法告诉您如何使您的流程具有幂等性,但不要试图解决“如果现场实例在中途关闭会发生什么”的问题,请考虑“我该如何设计过程中的每一步,以便它可以多次运行,使用相同的输入并且不会造成任何问题 - 如果你这样做,你会用一块石头杀死两只鸟。

于 2013-11-27T13:33:58.317 回答