Определение 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). Обратите внимание, что это может повлечь дополнительные расходы.

С другой стороны: добавление задержки в очередь или тайм-аут видимости не поможет в задержках между сбоями при чтении сообщений.

Другие вопросы по тегам