我有一个使用SQS排队作业的应用。理想情况下,我希望每项工作都能完成,但有些工作会失败。有时重新运行它们会起作用,有时它们会一直失败直到达到保留期。 。我希望尽可能长时间地将失败的工作留在队列中,以便给予他们最大的成功机会,因此我不想设置maxReceiveCount
。但我确实希望检测作业何时达到MessageRetentionPeriod
限制,因为我需要在作业完全失败时发送警报。目前我有14天的最大保留期,但到那时仍有一些工作尚未完成。
有没有办法检测作业即将到期的时间,并从那里将其发送到deadletter queue以进行其他处理?
答案 0 :(得分:2)
在您按照我的建议和assuming I've done the math for periods correctly之前,如果您检查的消息少于每20分钟9秒,那么您的状况会更好enabling a redrive policy on the queue。
SQS的“重启策略”允许您在收到阈值数量后将消息迁移到死信队列。 AWS允许的最大接收为1000,超过14天,每次接收大约20分钟。 (为简单起见,假设您的工作从未错过尝试读取队列消息。您可以调整数字以构建容错失败。)
如果您经常检查,则需要实施以下解决方案。
您可以在处理消息时检查此“截止日期”(当作业即将到期时),并且如果他们已经超过您放弃消息的时间,则将消息发送到deadletter队列。
要添加到当前例程的伪代码:
这是Powershell中的一个示例实现:
$queueUrl = "https://sqs.amazonaws.com/0000/my-queue"
$deadLetterQueueUrl = "https://sqs.amazonaws.com/0000/deadletter"
# Get the message retention period in seconds
$messageRetentionPeriod = (Get-SQSQueueAttribute -AttributeNames "MessageRetentionPeriod" -QueueUrl $queueUrl).Attributes.MessageRetentionPeriod
# Receive messages from our queue.
$queueMessages = @(receive-sqsmessage -QueueUrl $queueUrl -WaitTimeSeconds 5 -AttributeNames SentTimestamp)
foreach($message in $queueMessages)
{
# The sent timestamp is in epoch time.
$sentTimestampUnix = $message.Attributes.SentTimestamp
# For powershell, we need to do some quick conversion to get a DateTime.
$sentTimestamp = ([datetime]'1970-01-01 00:00:00').AddMilliseconds($sentTimestampUnix)
# Get the expiration time by adding the retention period to the sent time.
$expirationTime = $sentTimestamp.AddDays($messageRetentionPeriod / 86400 )
# I want my cutoff date to be one hour before the expiration time.
$cutoffDate = $expirationTime.AddHours(-1)
# Check if the cutoff date has passed.
if((Get-Date) -ge $cutoffDate)
{
# Cutoff Date has passed, move to deadletter queue
Send-SQSMessage -QueueUrl $deadLetterQueueUrl -MessageBody $message.Body
remove-sqsmessage -QueueUrl $queueUrl -ReceiptHandle $message.ReceiptHandle -Force
}
else
{
# Cutoff Date has not passed. Retry job?
}
}
这会为您处理的每条消息增加一些开销。这也假定您的消息处理程序将在截止时间和到期时间之间接收消息。确保您的应用程序经常轮询以接收消息。