Определение 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. Затем есть повторная попытка, но это мгновенная повторная попытка. Почему так, как правильно настроить это с экспоненциальной стратегией отката? Это повторная попытка, но не с экспоненциальной задержкой.


person Artur Skrzydło    schedule 20.05.2018    source источник
comment
почему вы не принимаете правильный ответ?   -  person Moose on the Loose    schedule 16.04.2019
comment
Точно, я пропустил это   -  person Artur Skrzydło    schedule 17.04.2019


Ответы (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 в их политике перенастройки (только ассоциация Maximum Receives и Dead Letter Queue). Таким образом, возможным обходным путем может быть самостоятельная обработка сбоев и установка задержек для конкретных сообщений (подробнее здесь) постепенно при каждой повторной постановке в очередь (возможно, это будет включать обработку счетчика повторов в заголовках и не использовать JMS). Обратите внимание, что за это может взиматься дополнительная плата.

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

person Pranjal    schedule 13.11.2018