Время ожидания видимости сообщения SQS устанавливается равным 0 при возникновении исключения и @JMSListener - PullRequest
0 голосов
/ 21 мая 2019

У меня есть простая служба Spring Boot, которая прослушивает очередь AWS SQS, используя JMSTemplate.Все работает как положено, когда сообщение правильно обрабатывается.

Я использую CLIENT_ACKNOWLEDGE, поэтому при возникновении исключения во время обработки сообщение снова принимается.Однако значение параметра «Тайм-аут видимости по умолчанию» в очереди SQS игнорируется, и сообщение сразу же принимается снова.

В очереди SQS настроено время ожидания по умолчанию по умолчанию 30 секунд, а политика повторного вождения составляет 20, получаемых допомещение сообщения в DLQ.

Я отключил службу и с помощью консоли SQS проверил, правильно ли установлено время ожидания видимости по умолчанию.Я также попытался добавить сообщение JMS к сигнатуре метода и выполнить ручную проверку.

Вот код для конфигурации JMS:

@Configuration
@EnableJms
class JmsConfig
{

    @Bean
    @Conditional(AWSEnvironmentCondition.class)
    public SQSConnectionFactory connectionFactory(@Value("${AWS_REGION}") String awsRegion)
    {
        return new SQSConnectionFactory(
            new ProviderConfiguration(),
            AmazonSQSClientBuilder.standard()
                                  .withRegion(Regions.fromName(awsRegion))
                                  .withCredentials(new DefaultAWSCredentialsProviderChain())
        );
    }

    @Bean
    public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory)
    {
        DefaultJmsListenerContainerFactory factory =
            new DefaultJmsListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setDestinationResolver(new DynamicDestinationResolver());
        factory.setConcurrency("3-10");
        factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
        factory.setErrorHandler(defaultErrorHandler());
        return factory;
    }

    @Bean
    public ErrorHandler defaultErrorHandler()
    {
        return new ErrorHandler()
        {
            @Override
            public void handleError(Throwable throwable)
            {
                LOG.error("JMS message listener error: {}", throwable.getMessage());
            }
        };
    }

    @Bean
    public JmsTemplate defaultJmsTemplate(ConnectionFactory connectionFactory)
    {
        return new JmsTemplate(connectionFactory);
    }
}

А вот код для прослушивателя:

@Component
public class MessagingListener
{
    @Autowired
    private MessageService _messageService;

    @Autowired
    private Validator _validator;

    @JmsListener(destination = "myqueue")
    public void receiveMessage(String messageJson)
    {
        try
        {
            LOG.info("Received message");

            // The following line throws an IOException is the message is not JSON.
            MyMessage myMessage = MAPPER.readvalue(messageJson, MyMessage.class);

            Set<ConstraintViolation<MyMessage>> _validator.validate(myMessage);
            if (CollectionUtils.isNotEmpty(violations))
            {
                String errorMessage = violations.stream()
                        .map(v -> String.join(" : ", v.getPropertyPath().iterator().next().getName(),
                                v.getMessage()))
                LOG.error("Exception occurred while validating the model, details: {}", errorMessage)
                throw new ValidationException(errorMessage);
            }
        }
        catch (IOException e)
        {
            LOG.error("Error parsing message", e);
            throw new ValidationException("Error parsing message, details: " + e.getMessage());
        }
    }
}

Когда в очередь SQS помещается сообщение с недопустимым JSON или JSON, которое не проходит проверку, сообщение очень быстро принимается 20 раз, а затем попадает в DLQ.Что нужно сделать, чтобы соблюдались настройки тайм-аута видимости по умолчанию в SQS?

...