Home > Software design >  AWS SQS, DLQ in spring boot
AWS SQS, DLQ in spring boot

Time:11-23

How do I add a DLQ configuration to my SQS configuration? I'm not sure how to integrate a DLQ with my existing queue. I'm using aws messaging and not JMS, so my annotation would be @SQSListener for my listener method. I have a config class that has following

@Bean
    public SimpleMessageListenerContainer messageListenerContainer(AmazonSQSAsync amazonSQSAsync) {
        SimpleMessageListenerContainerFactory factory = new SimpleMessageListenerContainerFactory();
        factory.setAmazonSqs(amazonSQSAsync);
        factory.setMaxNumberOfMessages(10);
        SimpleMessageListenerContainer simpleMessageListenerContainer = factory.createSimpleMessageListenerContainer();
        simpleMessageListenerContainer.setQueueStopTimeout(queueStopTimeout*1000);
        simpleMessageListenerContainer.setMessageHandler(messageHandler(amazonSQSAsync));
        return simpleMessageListenerContainer;
    }

    @Bean
    public QueueMessageHandler messageHandler(AmazonSQSAsync amazonSQSAsync) {
        QueueMessageHandlerFactory queueMessageHandlerFactory = new QueueMessageHandlerFactory();
        queueMessageHandlerFactory.setAmazonSqs(amazonSQSAsync);
        QueueMessageHandler messageHandler = queueMessageHandlerFactory.createQueueMessageHandler();
        return messageHandler;
    }

    @Bean
    public AmazonSQSAsync awsSqsAsync() {
        AmazonSQSAsyncClient amazonSQSAsyncClient  = new AmazonSQSAsyncClient(new DefaultAWSCredentialsProviderChain());
        amazonSQSAsyncClient.setRegion(Region.getRegion(Regions.fromName(region)));
        return new AmazonSQSBufferedAsyncClient(amazonSQSAsyncClient);
    }

I couldn't find any right documentation to correctly set retries so that if the retries exceed the threshold, the message should go to a dead-letter queue

CodePudding user response:

If I am not mistaken, setting the maximum retries, and associated DLQ is done on the Broker side, and not configurable as part of the listener.

Then in your code, you will do something like:

@SqsListener(value = "MainQueue", deletionPolicy = SqsMessageDeletionPolicy.NEVER)
public void receive(String message, @Header("SenderId") String senderId, Acknowledgment ack) throws IOException {

  ack.acknowledge();  

}

@SqsListener(value = "DLQ-AssociatedWithMain")
public void receiveDlq(String message) throws IOException {

}

If Message is NOT acknowledged, then it will be retried for a specific max period, then sent to DLQ.

=== Edited ===

The below for LocalStack are suggestions (Never Tested), However LocalStack (Free Version) as of now is supposed to support the AWS CLI:

As such, if you look at the AWS CLI: you use aws create-queue to create a Queue, and --attributes if you wanted to specify DLQ Information, though I believe you must also create the DLQ queue as well before referencing the RN.

  create-queue
--queue-name <value>
[--attributes <value>]
[--tags <value>]
[--cli-input-json <value>]
[--generate-cli-skeleton <value>]

DLQ Attribute Details:

The following attributes apply only to dead-letter queues:

RedrivePolicy – The string that includes the parameters for the dead-letter queue functionality of the source queue as a JSON object. The parameters are as follows:
    deadLetterTargetArn – The Amazon Resource Name (ARN) of the dead-letter queue to which Amazon SQS moves messages after the value of maxReceiveCount is exceeded.
    maxReceiveCount – The number of times a message is delivered to the source queue before being moved to the dead-letter queue. When the ReceiveCount for a message exceeds the maxReceiveCount for a queue, Amazon SQS moves the message to the dead-letter-queue.
RedriveAllowPolicy – The string that includes the parameters for the permissions for the dead-letter queue redrive permission and which source queues can specify dead-letter queues as a JSON object. The parameters are as follows:
    redrivePermission – The permission type that defines which source queues can specify the current queue as the dead-letter queue. Valid values are:
        allowAll – (Default) Any source queues in this Amazon Web Services account in the same Region can specify this queue as the dead-letter queue.
        denyAll – No source queues can specify this queue as the dead-letter queue.
        byQueue – Only queues specified by the sourceQueueArns parameter can specify this queue as the dead-letter queue.
    sourceQueueArns – The Amazon Resource Names (ARN)s of the source queues that can specify this queue as the dead-letter queue and redrive messages. You can specify this parameter only when the redrivePermission parameter is set to byQueue . You can specify up to 10 source queue ARNs. To allow more than 10 source queues to specify dead-letter queues, set the redrivePermission parameter to allowAll .

https://docs.aws.amazon.com/cli/latest/reference/sqs/create-queue.html



In LocalStack SQS Documentation, they have an example of creating an SQS Queue:

awslocal sqs create-queue --queue-name sample-queue
{
    "QueueUrl": "http://localhost:4566/000000000000/sample-queue"
}

So just take this example, create your DLQ, then create your Queue with --attributes to point to the DLQ RN.

https://docs.localstack.cloud/aws/sqs/

Hope this helps guide you in the right direction,

  • Related