Определение BackoffStrategy для SQS в AWS
Я хочу установить стратегию отсрочки для sqs в приложении Spring. Что я сделал, это:
@Bean
public ConnectionFactory sqsConnectionFactory() {
PredefinedBackoffStrategies.ExponentialBackoffStrategy backoffStrategy = new PredefinedBackoffStrategies.ExponentialBackoffStrategy(3, 27);
RetryPolicy retryPolicy = new RetryPolicy(PredefinedRetryPolicies.DEFAULT_RETRY_CONDITION, backoffStrategy, PredefinedRetryPolicies.DEFAULT_MAX_ERROR_RETRY, false);
return SQSConnectionFactory.builder()
.withRegion(Region.getRegion(Regions.fromName(region)))
.withAWSCredentialsProvider(new DefaultAWSCredentialsProviderChain())
.withClientConfiguration(new ClientConfiguration().withRetryPolicy(retryPolicy))
.build();
}
, но это не имеет никакого эффекта. Я читаю из очереди SQS из простого @JmsListener
метод. В этом методе есть вызов к другому API. Этот API возвращает мне ошибку 404. Затем повторная попытка, но повторная попытка. Почему, как правильно настроить это с экспоненциальной стратегией отсрочки? Это повторная попытка, но не с экспоненциальной задержкой.
1 ответ
Стратегия отсрочки, установленная в ClientConfiguration
в вашем коде используется для обеспечения задержки попыток клиента AWS подключиться к сервисам AWS. Это означает, что выбранная вами стратегия будет использоваться, если (скажем, по какой-то причине) клиенту AWS SQS не удастся подключиться к сервису AWS SQS для получения сообщения (или опроса новых сообщений). Если такой сбой происходит, следующая попытка должна быть сделана после задержки, предоставленной ExponentialBackoffStrategy
, Для более подробной информации обратитесь к официальной документации здесь.
Причина немедленной повторной попытки
В вашем случае сообщение уже было получено из службы SQS базовым клиентом (который используется в Spring @JmsListener
). Неудача для этого самого шага использовала бы ExponentialBackoffStrategy
, Сбой после этого (например, исключение, генерируемое после 404) вызовет подтверждение сбоя службе SQS, и служба немедленно сделает сообщение видимым для потребления.
Как связать стратегию отсрочки с доставкой
К сожалению, эта стратегия не может быть связана с ошибками потребления сообщений. Задержка, которая требуется, на самом деле является задержкой повторной доставки спецификации JMS 2.0. Но провайдер SQS JMS, который вы, похоже, используете, - это https://github.com/awslabs/amazon-sqs-java-messaging-lib который является реализацией JMS 1.1. Ниже приводится то же цитата из их документации:
Этот проект основывается на AWS SDK для Java, чтобы использовать Amazon SQS в качестве поставщика JMS (как определено в спецификации 1.1)
Кроме того, SQS не имеет ничего подобного redelivery-delay
в их политике redrive (только Maximum Receives
а также Dead Letter Queue
ассоциация). Таким образом, возможный обходной путь будет заключаться в том, чтобы обрабатывать сбои самостоятельно и устанавливать определенные задержки для сообщений (подробнее здесь) для каждой повторной очереди (это может включать обработку количества повторов в заголовках, возможно, и без использования JMS). Обратите внимание, что это может повлечь дополнительные расходы.
С другой стороны: добавление задержки в очередь или тайм-аут видимости не поможет в задержках между сбоями при чтении сообщений.