Reputation: 25780
In my Spring Boot application I'm listening message queue. When a message appears I need to execute it synchronously(one by one) in some task-executor.
I'm using Amazon SQS, this is my config:
/**
* AWS Credentials Bean
*/
@Bean
public AWSCredentials awsCredentials() {
return new BasicAWSCredentials(accessKey, secretAccessKey);
}
/**
* AWS Client Bean
*/
@Bean
public AmazonSQS amazonSQSAsyncClient() {
AmazonSQS sqsClient = new AmazonSQSClient(awsCredentials());
sqsClient.setRegion(Region.getRegion(Regions.US_EAST_1));
return sqsClient;
}
/**
* AWS Connection Factory
*/
@Bean
public SQSConnectionFactory connectionFactory() {
SQSConnectionFactory.Builder factoryBuilder = new SQSConnectionFactory.Builder(
Region.getRegion(Regions.US_EAST_1));
factoryBuilder.setAwsCredentialsProvider(new AWSCredentialsProvider() {
@Override
public AWSCredentials getCredentials() {
return awsCredentials();
}
@Override
public void refresh() {
}
});
return factoryBuilder.build();
}
/**
* Registering QueueListener for queueName
*/
@Bean
public DefaultMessageListenerContainer defaultMessageListenerContainer() {
DefaultMessageListenerContainer messageListenerContainer = new DefaultMessageListenerContainer();
messageListenerContainer.setConnectionFactory(connectionFactory());
messageListenerContainer.setMessageListener(new MessageListenerAdapter(new QueueListener()));
messageListenerContainer.setDestinationName(queueName);
return messageListenerContainer;
}
Also I need to have possibility to check the status of this task-executor, for example - number of scheduled tasks.
Is it a good idea to use Spring SyncTaskExecutor
for this purpose ? If so, could you please show an example how it can be used with Spring Boot.
Upvotes: 1
Views: 5165
Reputation: 24561
EDIT:
After revealing your messaging technology and Spring configuration for it, simplest way for you is to configure SyncTaskExecutor
(or Executors.newFixedThreadPool(1)
would do the job also) as executor for your DefaultMessageListenerContainer
. Use this method.
You can register Task executor as separate bean (via @Bean annotation) and autowire it to defaultMessageListenerContainer()
method (just add TaskExectuor
as parameter).
Below answer is relevant for JMS messaging. It was created before AWS SQS usage was revealed in question:
You didn't mention which messaging technology are you using, therefore I assume JMS.
If synchronous execution is requirement, I believe you can't use native JMS listeners (need to avoid SimpleJmsListenerContainerFactory
or SimleMessageListenerContainer
).
Instead I would suggest to use @JmsListener
annotation with DefaultJmsListenerContainerFactory
(this uses long polling instead of native JMS listeners) and configure SyncTaskExecutor
(or Executors.newFixedThreadPool(1)
would do the job also) as executor for mentioned container factory: DefaultJmsListenerContainerFactory.setTaskExecutor()
.
This is simple Spring Boot JMS example with DefaultJmsListenerContainerFactory configured. You just need to plug in suitable task executor.
Upvotes: 1