使用JMS的SQS的nack的定制接收超时

时间:2019-01-31 12:35:15

标签: java amazon-sqs

否定确认的行为是将接收到的消息的可见性超时更改为0。在为JMS创建SQS Factory的情况下,不可配置NACK_TIMEOUT的值。

https://github.com/awslabs/amazon-sqs-java-messaging-lib/blob/master/src/main/java/com/amazon/sqs/javamessaging/acknowledge/NegativeAcknowledger.java#L99

当接收到一条消息,并且处理失败(侦听器方法引发错误)时,将立即再次接收到该消息。在大多数情况下,可以在一定延迟下处理消息。

是否可以将其配置为不更改可见性超时,以便它遵守队列的默认接收超时配置?

2 个答案:

答案 0 :(得分:0)

显然有一种方法,有些笨拙,但是我没有找到更好的解决方法,其想法是,当您创建客户端时,您可以附加自己的请求处理程序:

    return AmazonSQSAsyncClientBuilder.standard()
        .withRequestHandlers(new RequestHandler2() {
            @Override
            public AmazonWebServiceRequest beforeExecution(AmazonWebServiceRequest request) {
                if (request instanceof ChangeMessageVisibilityBatchRequest) {
                    ((ChangeMessageVisibilityBatchRequest) request).getEntries().forEach(changeMessageVisibilityBatchRequestEntry -> {
                        changeMessageVisibilityBatchRequestEntry.setVisibilityTimeout(15);
                    });
                    log.debug("Changed visibility timeout for request {}", request);
                }
                return request;
            }
        })
    ;

答案 1 :(得分:0)

完全不希望发送ChangeMessageVisibility请求(重置当前可见性计时器)并且仅希望依靠默认队列可见性超时的人们可以使用在lombok的帮助下编写的以下AmazonSQS包装器: / p>

public AmazonSQS amazonSqs(AWSCredentialsProvider credentialsProvider) {
    AmazonSQS amazonSQS = AmazonSQSClientBuilder.standard()
            .withRegion(region)
            (...)
            .build();

    return new IgnoringChangeVisibilityAmazonSqs(amazonSQS);
}

@Slf4j
@RequiredArgsConstructor
public class IgnoringChangeVisibilityAmazonSqs implements AmazonSQS {

    private interface ChangeVisibilityOperations {
        ChangeMessageVisibilityResult changeMessageVisibility(ChangeMessageVisibilityRequest changeMessageVisibilityRequest);
        ChangeMessageVisibilityResult changeMessageVisibility(String queueUrl, String receiptHandle, Integer visibilityTimeout);
        ChangeMessageVisibilityBatchResult changeMessageVisibilityBatch(ChangeMessageVisibilityBatchRequest request);
        ChangeMessageVisibilityBatchResult changeMessageVisibilityBatch(String queueUrl, List<ChangeMessageVisibilityBatchRequestEntry> entries);
    }

    @Delegate(excludes = ChangeVisibilityOperations.class)
    private final AmazonSQS amazonSqs;

    @Override
    public ChangeMessageVisibilityResult changeMessageVisibility(ChangeMessageVisibilityRequest changeMessageVisibilityRequest) {
        log.info("Ignoring ChangeMessageVisibilityRequest");
        return new ChangeMessageVisibilityResult();
    }

    @Override
    public ChangeMessageVisibilityResult changeMessageVisibility(String queueUrl, String receiptHandle, Integer visibilityTimeout) {
        log.info("Ignoring ChangeMessageVisibilityRequest");
        return new ChangeMessageVisibilityResult();
    }

    @Override
    public ChangeMessageVisibilityBatchResult changeMessageVisibilityBatch(ChangeMessageVisibilityBatchRequest request) {
        log.info("Ignoring ChangeMessageVisibilityBatchRequest");
        return changeMessageVisibilityBatch(request.getQueueUrl(), request.getEntries());
    }

    @Override
    public ChangeMessageVisibilityBatchResult changeMessageVisibilityBatch(String queueUrl, List<ChangeMessageVisibilityBatchRequestEntry> entries) {
        log.info("Ignoring ChangeMessageVisibilityBatchRequest");
        List<ChangeMessageVisibilityBatchResultEntry> results = entries.stream().map(request ->
                new ChangeMessageVisibilityBatchResultEntry().withId(request.getId()))
                .collect(Collectors.toList());
        return new ChangeMessageVisibilityBatchResult().withSuccessful(results);
    }
}