SQS标准队列触发Lambda时,可见性超时内会收到重复消息吗?
直接说结论:正常情况下不会。
为什么不会?看SQS的可见性超时机制
SQS的可见性超时就是专门用来避免这种情况的:
消息被接收后会立即保留在队列中。为防止其他消费者再次处理该消息,Amazon SQS会设置可见性超时,即在这段时间内阻止其他消费者接收和处理该消息。
当Lambda从SQS拉取消息时,SQS会自动给这条消息加上可见性超时(默认30秒,可自行配置)。在这个超时周期内,这条消息相当于被“隐藏”了,任何其他消费者(包括其他Lambda实例)都无法拉取到它。
只要当前处理这条消息的Lambda实例还在运行,且可见性超时未过期,就不会有其他Lambda实例拿到这条消息。
那什么时候会出现重复消息?
你提到的重复消息场景,和“处理中”的情况无关,是发生在处理完成后删除消息的阶段:
在极少数情况下,当您接收或删除消息时,存储消息副本的某台服务器可能不可用。此时,该不可用服务器上的消息副本不会被删除,您在接收消息时可能会再次收到该副本。
简单来说:你已经处理完消息并调用了删除接口,但因为SQS是分布式存储,某台存储消息副本的服务器不可用,导致该副本未被删除,后续可能被再次拉取,从而产生重复。这是处理完成后的重复,而非处理过程中多个Lambda同时处理同一条消息。
另外还有一种可能:如果Lambda处理消息的时间超过了可见性超时,SQS会把消息重新设为可见,此时其他Lambda实例就可能拉取到它。这种情况可以通过调大可见性超时,或者在处理过程中调用ChangeMessageVisibility接口延长超时来避免。
最后提醒
由于SQS标准队列本身不保证消息仅被处理一次,你的应用必须实现幂等性设计——比如用消息ID作为唯一标识,处理前先校验是否已处理过,确保就算收到重复消息,也不会产生重复操作或异常。
内容的提问来源于stack exchange,提问作者JF9199

