Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

AmazonSQS and Spring for Messaging Queue

DZone's Guide to

AmazonSQS and Spring for Messaging Queue

Read all about using AmazonSQS and Spring for messaging queues.

· Web Dev Zone ·
Free Resource

Deploy code to production now. Release to users when ready. Learn how to separate code deployment from user-facing feature releases with LaunchDarkly.

The next post will demonstrate how to use Spring JMS templates and DLMC’S together with AmazonSQS API in order to place message queue.

Why would I use Amazon SQS?

1.  Easy to configure

2. Cross-platfom support

3. Earn from your self redundant, conjunction and scaling worries.

Why I wouldn’t use Amazon SQS?

1. If the latency requirement demands less than  ~20 MS

2. Costs ~0.00005$ per message

I came across a nice open source project called: Nevado which wrapping the Amazon SQS API in a very neat way.

Add this to your maven dependency:

1
2
3
4
5
<dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>nevado-jms</artifactId>
<version>1.2.4</version>
</dependency>

Now let’s configure Spring beans to integrate nicely with AmazonSQS:

1. Connection factory:

<bean id="sqsConnectorFactory" class="org.skyscreamer.nevado.jms.connector.amazonaws.AmazonAwsSQSConnectorFactory"/>

Pay attention that within this wrapper we need to set aws.accessKey and aws.secretKey. We get those keys from AmazonSQS account portal:

<bean id="connectionFactory" class="org.skyscreamer.nevado.jms.NevadoConnectionFactory">
<property name="sqsConnectorFactory" ref="sqsConnectorFactory"/>
<property name="awsAccessKey" value="${aws.accessKey}"/>
<property name="awsSecretKey" value="${aws.secretKey}"/>
</bean>

2. Create the queue

<bean id="myQueue" class="org.skyscreamer.nevado.jms.destination.NevadoQueue">
<constructor-arg value="${aws.sqs.queue.name}"/>
</bean>

3. Create Jms template (which will be injected later in the code to send messages):

<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="defaultDestinationName" value="${aws.sqs.queue.name}"/>
<property name="connectionFactory" ref="cachedConnectionFactory"/>
</bean>

3. Add listeners:

3.a I am using SimpleMessageListenerContainer which has the ability to cache connections, run concurrent consumers, set error listeners and more.

<bean id="simpleMessageListenerContainer" class="org.springframework.jms.listener.SimpleMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory"/>
<property name="messageListener" ref="listener"/>
<property name="destination" ref="myQueue"/>
<property name="errorHandler" ref="amazonMessageListener"/>
<property name="concurrency" value="20"/>
<property name="taskExecutor" ref="listenerThreadPoolTaskExecutor"/>
</bean>

3.b Let’s add Thread pool for the listener’s executors:

<bean id="listenerThreadPoolTaskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="70"/>
<property name="maxPoolSize" value="70"/>
<property name="daemon" value="true"/>
<property name="keepAliveSeconds" value="60"/>
</bean>

3.c Add Caching connections support:

<bean id="cachedConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="connectionFactory"/>
<property name="sessionCacheSize" value="10"/>
</bean>

3.d Create MessageAdapter to hook everything up and to set pojo as our message listener(amazonMessageListener):

<bean id="listener" class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
<property name="delegate" ref="amazonMessageListener"/>
<property name="defaultListenerMethod" value="onMessage"/>
<property name="defaultResponseDestination" ref="myQueue"/>
</bean>

Idan.

Deploy code to production now. Release to users when ready. Learn how to separate code deployment from user-facing feature releases with LaunchDarkly.

Topics:
web dev ,spring ,amazonsqs

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}