Spring Cloud AWS is the Spring project that connects a Spring Boot app to AWS services. Its SQS module sends messages to an Amazon SQS queue with SqsTemplate and receives them with @SqsListener. Amazon SQS is a managed message queue, where one part of our system puts a message and another part reads it later, so the two never wait for each other.
We use Spring Cloud AWS SQS when a web request should return at once and the slow work can happen later. For example, a request creates an invoice, and another service emails it a moment later. The starter gives us a ready SqsTemplate bean and converts our objects to JSON and back.
The following example sends one invoice to the queue invoice-queue and receives it in a listener method.
// 1. Send: the record is written to the queue as JSON
SendResult<InvoiceCreated> result = sqsTemplate.send("invoice-queue", new InvoiceCreated(1, "Lokesh", 120));
UUID messageId = result.messageId(); // de34536b-c578-48f6-8358-11ec91e92c79
// 2. Receive: Spring polls the queue and calls this method for every message
@SqsListener("invoice-queue")
public void onInvoiceCreated(InvoiceCreated invoice) {
log.info("Received invoice {} for {}", invoice.number(), invoice.customer()); // Received invoice 1 for Lokesh
}
Notice that we never call the AWS SDK, and that we use the queue name instead of its URL. The listener gets the record back as a Java object. Next we set up the project, point it at LocalStack, process more than 10 messages at the same time and pick an acknowledgement mode.
1. Spring Cloud AWS Setup
Spring Cloud AWS has its own version number and its own BOM, and each release line works with one Spring Boot line. Spring Cloud AWS 4.x is built for Spring Boot 4.0.x, so a Spring Boot 3.5 project stays on Spring Cloud AWS 3.4.x.
| Spring Cloud AWS | Spring Boot | Spring Framework |
|---|---|---|
| 3.3.x | 3.4.x | 6.2.x |
| 3.4.x | 3.5.x | 6.2.x |
| 4.x | 4.0.x | 7.0.x |
We import the BOM in dependencyManagement and add the SQS starter, which brings the AWS SDK client. We also add spring-boot-starter-jackson, because the JSON conversion uses Jackson and a plain Spring Boot 4 app does not have it on the classpath.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.awspring.cloud</groupId>
<artifactId>spring-cloud-aws-dependencies</artifactId>
<version>4.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.awspring.cloud</groupId>
<artifactId>spring-cloud-aws-starter-sqs</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jackson</artifactId>
</dependency>
</dependencies>
The SQS client needs credentials and a region, and all properties start with spring.cloud.aws. In production we leave the two credential properties out, so the AWS SDK reads them from environment variables or from the IAM role of the server.
spring.cloud.aws.credentials.access-key=test
spring.cloud.aws.credentials.secret-key=test
spring.cloud.aws.region.static=us-east-1
2. SQS Endpoint Property for LocalStack
By default, the SQS client calls the real AWS endpoint of the configured region. During development we point it at LocalStack instead, which runs a copy of the SQS API in a Docker container on our machine. The property spring.cloud.aws.sqs.endpoint overrides the SQS endpoint, and spring.cloud.aws.endpoint overrides the endpoint of every AWS client at once. LocalStack accepts any access key and secret key.
spring.cloud.aws.sqs.endpoint=http://localhost:4566
# Create a queue on first use (CREATE is the default; use FAIL in production)
spring.cloud.aws.sqs.queue-not-found-strategy=CREATE
The second property decides what happens when the queue does not exist. With CREATE the framework creates the queue on first use, with FAIL the app throws an exception at startup, and with IGNORE the listener logs a warning and skips the queue.
docker run -d --name localstack -p 4566:4566 localstack/localstack:4.12.0
In real AWS we create the queue in the SQS console and set the strategy to FAIL.
3. Spring Cloud AWS SQS Example
The following example is an invoice service. A producer sends an InvoiceCreated message for every new invoice, and a listener emails the invoice to the customer. The payload is a Java record, which goes into the queue as JSON.
public record InvoiceCreated(int number, String customer, int amount) {
}
The project uses Spring Boot 4.0.8, Spring Cloud AWS 4.2.0, Java 25, LocalStack 4.12.0 and Testcontainers 2.0.5. The complete code, with a test that starts LocalStack, is in the GitHub repository.

4. Sending Messages with SqsTemplate
Spring Boot creates one SqsTemplate bean for us. The bean is thread-safe, so we inject the same one into every class that sends messages. The short form of send() takes the queue name or URL and the payload. The lambda form also takes extras such as a header or a delay.
SendResult<InvoiceCreated> result = sqsTemplate.send(to -> to
.queue("invoice-queue")
.payload(invoice)
.header("source", "web"));
UUID messageId = result.messageId(); // de34536b-c578-48f6-8358-11ec91e92c79
String queue = result.endpoint(); // invoice-queue
Each header becomes an SQS message attribute, and the listener reads it with @Header. Sending many messages one by one costs one HTTP request each. The sendMany() method uses the SQS batch API, which accepts at most 10 messages per request. Since Spring Cloud AWS 4.2.0 the template splits a longer list into batches of 10, so 25 invoices become three requests.
List<Message<InvoiceCreated>> messages = invoices.stream()
.map(invoice -> MessageBuilder.withPayload(invoice).setHeader("source", "import").build())
.toList();
SendResult.Batch<InvoiceCreated> batch = sqsTemplate.sendMany("invoice-queue", messages);
int sent = batch.successful().size(); // 25
int failed = batch.failed().size(); // 0
If one message in a batch fails, the template throws SendBatchOperationFailedException, which lists the failed messages.
5. Receiving Messages with @SqsListener
A method annotated with @SqsListener becomes a message listener. Spring Cloud AWS creates a listener container for it, which polls the queue in a loop. The container uses long polling, so a poll waits up to 10 seconds for messages instead of returning empty at once. For every message the container converts the JSON body to the parameter type and calls our method on a worker thread.
@SqsListener(value = "invoice-queue", id = "invoices")
public void onInvoiceCreated(InvoiceCreated invoice, @Header("source") String source) {
log.info("Received invoice {} for {} from {}", invoice.number(), invoice.customer(), source);
emailSender.send(invoice);
}
The id names the container and its threads, which helps when we read the logs. The method parameters decide what we get.
| Parameter | What the listener method gets |
|---|---|
| InvoiceCreated invoice | The payload, converted from JSON. |
| Message<InvoiceCreated> message | The payload plus the headers. |
| @Header(“source”) String source | One message attribute. Add required = false when the sender may leave it out. |
| Acknowledgement ack | Deletes the message in MANUAL mode (see section 7). |
[ invoices-1] com.howtodoinjava.sqs.InvoiceListener : Received invoice 1 for Lokesh from web
[ invoices-1] com.howtodoinjava.sqs.EmailSender : Emailed invoice 1 to Lokesh
6. Processing More Than 10 SQS Messages Concurrently
By default, a listener container processes at most 10 messages of a queue at the same time. The reason is that maxConcurrentMessages defaults to 10, and one poll returns at most 10 messages. Two settings change the throughput.
| Setting | Default | What it does |
|---|---|---|
| maxConcurrentMessages | 10 | The number of messages of one queue processed at the same time, which is also the thread count per queue. |
| maxMessagesPerPoll | 10 | The number of messages asked for in one poll. SQS returns at most 10 per request. |
| pollTimeout | 10 s | The time one poll waits for messages. |
We set the values in the annotation for one listener, or in application.properties for every listener in the app. The annotation value wins, and the limit applies per queue.
@SqsListener(value = "invoice-queue", id = "invoices", maxConcurrentMessages = "20", maxMessagesPerPoll = "10")
public void onInvoiceCreated(InvoiceCreated invoice, @Header("source") String source) {
spring.cloud.aws.sqs.listener.max-concurrent-messages=10
spring.cloud.aws.sqs.listener.max-messages-per-poll=10
spring.cloud.aws.sqs.listener.poll-timeout=10s
With 25 invoices in the queue, the container polls 10 more before the first 10 finish, and the log shows threads invoices-1 to invoices-20 working at the same time.
[ invoices-1] com.howtodoinjava.sqs.InvoiceListener : Received invoice 121 for Customer 121 from import
...
[ invoices-11] com.howtodoinjava.sqs.InvoiceListener : Received invoice 106 for Customer 106 from import
...
[ invoices-20] com.howtodoinjava.sqs.InvoiceListener : Received invoice 115 for Customer 115 from import
[ invoices-1] com.howtodoinjava.sqs.EmailSender : Emailed invoice 121 to Customer 121
Each message in flight takes one thread, so a value such as 200 means 200 threads per queue. For listeners that mostly wait on a database or an HTTP call, Spring Cloud AWS 4.1 and later can run the container on virtual threads.
7. Acknowledgement Modes
In SQS, acknowledging a message means deleting it from the queue. A received message only becomes invisible for the visibility timeout, which is 30 seconds by default. If nobody deletes the message in that time, SQS delivers it again. The listener container deletes messages for us, and the acknowledgementMode decides when.
| Mode | When the message is deleted | Use it when |
|---|---|---|
| ON_SUCCESS (default) | After our method returns without an exception. A failed message comes back after the visibility timeout. | We want a retry on every error. |
| ALWAYS | After our method returns or throws. | A retry would not help, such as a malformed message. |
| MANUAL | Only when we call acknowledge() on the Acknowledgement parameter. | We decide per message, such as after a database commit. |
We set the mode in the annotation. In MANUAL mode the method gets an Acknowledgement parameter, and a message we never acknowledge comes back after the visibility timeout.
@SqsListener(value = "invoice-audit-queue", id = "audit", acknowledgementMode = "MANUAL")
public void onInvoiceCreated(Message<InvoiceCreated> message, Acknowledgement ack) {
InvoiceCreated invoice = message.getPayload();
log.info("Audit record written for invoice {}", invoice.number());
ack.acknowledge(); // deletes the message from the queue
}
A message that fails on every retry comes back forever. The fix is a dead-letter queue, a second queue that SQS moves a message to after a chosen number of receives. We set it on the main queue, and the listener needs no change.

8. FIFO Queues in Brief
A FIFO queue delivers the messages of one message group in the order they were sent, and each message once. We give every message a messageGroupId, such as the customer, and a messageDeduplicationId, such as the invoice number. Two messages with the same deduplication id within 5 minutes count as one.
SendResult<InvoiceCreated> result = sqsTemplate.send(to -> to
.queue("invoice-queue.fifo")
.payload(invoice)
.messageGroupId(invoice.customer())
.messageDeduplicationId(String.valueOf(invoice.number())));
The listener side needs no FIFO code. A queue name ending with .fifo is set up as a FIFO queue, and the container processes the messages of one group one after the other, with different groups in parallel.
9. Testing with Testcontainers
In a test we do not want a container that someone has to start by hand. Testcontainers starts LocalStack from the test, and @ServiceConnection points every AWS client of the app at that container, so the test needs no endpoint property. The test scope also needs spring-boot-testcontainers, spring-cloud-aws-testcontainers, testcontainers-localstack and testcontainers-junit-jupiter. The listener runs on another thread, so the test waits with Awaitility until the message shows up.
@Container
@ServiceConnection
static LocalStackContainer localStack =
new LocalStackContainer(DockerImageName.parse("localstack/localstack:4.12.0"));
10. Conclusion
Spring Cloud AWS SQS takes the AWS SDK calls out of our code. We send with SqsTemplate by queue name and receive with a @SqsListener method that gets our record back. One property, spring.cloud.aws.sqs.endpoint, points the app at LocalStack.
When the queue grows, maxConcurrentMessages raises the number of messages in flight above 10, and the acknowledgement mode decides whether a failed message comes back for a retry.
11. References
- Spring Cloud AWS reference, SQS integration
- Spring Cloud AWS on GitHub
- Amazon SQS Developer Guide
- Testcontainers LocalStack module
- Spring Boot Testcontainers support
Happy Learning !!
Hello , After I clone the project and modify aws configuration according to my account i got below error
2025-01-12T23:45:26.114+05:30 WARN 20148 — [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization – cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean ‘io.awspring.cloud.messaging.internalEndpointRegistryBeanName’
Please provide the complete stack trace.
Please find below full log trace:
2025-01-16T07:00:35.302+05:30 WARN 9148 — [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization – cancelling refresh attempt: org.springframework.context.ApplicationContextException: Failed to start bean ‘io.awspring.cloud.messaging.internalEndpointRegistryBeanName’
2025-01-16T07:00:40.319+05:30 INFO 9148 — [ main] o.apache.catalina.core.StandardService : Stopping service [Tomcat]
2025-01-16T07:00:40.366+05:30 INFO 9148 — [ main] .s.b.a.l.ConditionEvaluationReportLogger :
Error starting ApplicationContext. To display the condition evaluation report re-run your application with ‘debug’ enabled.
2025-01-16T07:00:40.410+05:30 ERROR 9148 — [ main] o.s.boot.SpringApplication : Application run failed
org.springframework.context.ApplicationContextException: Failed to start bean ‘io.awspring.cloud.messaging.internalEndpointRegistryBeanName’
at org.springframework.context.support.DefaultLifecycleProcessor.doStart(DefaultLifecycleProcessor.java:181) ~[spring-context-6.0.9.jar:6.0.9]
at org.springframework.context.support.DefaultLifecycleProcessor$LifecycleGroup.start(DefaultLifecycleProcessor.java:356) ~[spring-context-6.0.9.jar:6.0.9]
at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[na:na]
at org.springframework.context.support.DefaultLifecycleProcessor.startBeans(DefaultLifecycleProcessor.java:155) ~[spring-context-6.0.9.jar:6.0.9]
at org.springframework.context.support.DefaultLifecycleProcessor.onRefresh(DefaultLifecycleProcessor.java:123) ~[spring-context-6.0.9.jar:6.0.9]
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:958) ~[spring-context-6.0.9.jar:6.0.9]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:611) ~[spring-context-6.0.9.jar:6.0.9]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.1.0.jar:3.1.0]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:733) ~[spring-boot-3.1.0.jar:3.1.0]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:435) ~[spring-boot-3.1.0.jar:3.1.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) ~[spring-boot-3.1.0.jar:3.1.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1305) ~[spring-boot-3.1.0.jar:3.1.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1294) ~[spring-boot-3.1.0.jar:3.1.0]
at com.example.springawssqsexample.SpringAwsSqsExampleApplication.main(SpringAwsSqsExampleApplication.java:16) ~[classes/:na]
Caused by: java.util.concurrent.CompletionException: io.awspring.cloud.sqs.QueueAttributesResolvingException: Error resolving attributes for queue HowToDoInJava with strategy CREATE and queueAttributesNames []
at java.base/java.util.concurrent.CompletableFuture.encodeRelay(CompletableFuture.java:368) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.completeRelay(CompletableFuture.java:377) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$UniCompose.tryFire(CompletableFuture.java:1152) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162) ~[na:na]
at software.amazon.awssdk.utils.CompletableFutureUtils.lambda$forwardExceptionTo$0(CompletableFutureUtils.java:79) ~[utils-2.20.55.jar:na]
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162) ~[na:na]
at software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncApiCallMetricCollectionStage.lambda$execute$0(AsyncApiCallMetricCollectionStage.java:54) ~[sdk-core-2.20.55.jar:na]
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162) ~[na:na]
at software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncApiCallTimeoutTrackingStage.lambda$execute$2(AsyncApiCallTimeoutTrackingStage.java:67) ~[sdk-core-2.20.55.jar:na]
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162) ~[na:na]
at software.amazon.awssdk.utils.CompletableFutureUtils.lambda$forwardExceptionTo$0(CompletableFutureUtils.java:79) ~[utils-2.20.55.jar:na]
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162) ~[na:na]
at software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncRetryableStage$RetryingExecutor.maybeAttemptExecute(AsyncRetryableStage.java:103) ~[sdk-core-2.20.55.jar:na]
at software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncRetryableStage$RetryingExecutor.maybeRetryExecute(AsyncRetryableStage.java:184) ~[sdk-core-2.20.55.jar:na]
at software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncRetryableStage$RetryingExecutor.lambda$attemptExecute$1(AsyncRetryableStage.java:159) ~[sdk-core-2.20.55.jar:na]
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162) ~[na:na]
at software.amazon.awssdk.utils.CompletableFutureUtils.lambda$forwardExceptionTo$0(CompletableFutureUtils.java:79) ~[utils-2.20.55.jar:na]
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162) ~[na:na]
at software.amazon.awssdk.core.internal.http.pipeline.stages.MakeAsyncHttpRequestStage.lambda$null$0(MakeAsyncHttpRequestStage.java:103) ~[sdk-core-2.20.55.jar:na]
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture.completeExceptionally(CompletableFuture.java:2162) ~[na:na]
at software.amazon.awssdk.core.internal.http.pipeline.stages.MakeAsyncHttpRequestStage.lambda$executeHttpRequest$3(MakeAsyncHttpRequestStage.java:165) ~[sdk-core-2.20.55.jar:na]
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$Completion.run(CompletableFuture.java:482) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
at java.base/java.lang.Thread.run(Thread.java:840) ~[na:na]
Caused by: io.awspring.cloud.sqs.QueueAttributesResolvingException: Error resolving attributes for queue HowToDoInJava with strategy CREATE and queueAttributesNames []
at io.awspring.cloud.sqs.QueueAttributesResolver.wrapException(QueueAttributesResolver.java:90) ~[spring-cloud-aws-sqs-3.0.0.jar:3.0.0]
at java.base/java.util.concurrent.CompletableFuture.uniExceptionally(CompletableFuture.java:990) ~[na:na]
at java.base/java.util.concurrent.CompletableFuture$UniExceptionally.tryFire(CompletableFuture.java:974) ~[na:na]
… 46 common frames omitted
Caused by: software.amazon.awssdk.core.exception.SdkClientException: Unable to execute HTTP request: Acquire operation took longer than the configured maximum time. This indicates that a request cannot get a connection from the pool within the specified maximum time. This can be due to high request rate.
Consider taking any of the following actions to mitigate the issue: increase max connections, increase acquire timeout, or slowing the request rate.
Increasing the max connections can increase client throughput (unless the network interface is already fully utilized), but can eventually start to hit operation system limitations on the number of file descriptors used by the process. If you already are fully utilizing your network interface or cannot further increase your connection count, increasing the acquire timeout gives extra time for requests to acquire a connection before timing out. If the connections doesn’t free up, the subsequent requests will still timeout.
If the above mechanisms are not able to fix the issue, try smoothing out your requests so that large traffic bursts cannot overload the client, being more efficient with the number of times you need to call AWS, or by increasing the number of hosts sending requests.
at software.amazon.awssdk.core.exception.SdkClientException$BuilderImpl.build(SdkClientException.java:111) ~[sdk-core-2.20.55.jar:na]
at software.amazon.awssdk.core.exception.SdkClientException.create(SdkClientException.java:47) ~[sdk-core-2.20.55.jar:na]
at software.amazon.awssdk.core.internal.http.pipeline.stages.utils.RetryableStageHelper.setLastException(RetryableStageHelper.java:223) ~[sdk-core-2.20.55.jar:na]
at software.amazon.awssdk.core.internal.http.pipeline.stages.utils.RetryableStageHelper.setLastException(RetryableStageHelper.java:218) ~[sdk-core-2.20.55.jar:na]
at software.amazon.awssdk.core.internal.http.pipeline.stages.AsyncRetryableStage$RetryingExecutor.maybeRetryExecute(AsyncRetryableStage.java:182) ~[sdk-core-2.20.55.jar:na]
… 22 common frames omitted
Caused by: java.lang.Throwable: Acquire operation took longer than the configured maximum time. This indicates that a request cannot get a connection from the pool within the specified maximum time. This can be due to high request rate.
Consider taking any of the following actions to mitigate the issue: increase max connections, increase acquire timeout, or slowing the request rate.
Increasing the max connections can increase client throughput (unless the network interface is already fully utilized), but can eventually start to hit operation system limitations on the number of file descriptors used by the process. If you already are fully utilizing your network interface or cannot further increase your connection count, increasing the acquire timeout gives extra time for requests to acquire a connection before timing out. If the connections doesn’t free up, the subsequent requests will still timeout.
If the above mechanisms are not able to fix the issue, try smoothing out your requests so that large traffic bursts cannot overload the client, being more efficient with the number of times you need to call AWS, or by increasing the number of hosts sending requests.
at software.amazon.awssdk.http.nio.netty.internal.utils.NettyUtils.decorateException(NettyUtils.java:69) ~[netty-nio-client-2.20.55.jar:na]
at software.amazon.awssdk.http.nio.netty.internal.NettyRequestExecutor.handleFailure(NettyRequestExecutor.java:309) ~[netty-nio-client-2.20.55.jar:na]
at software.amazon.awssdk.http.nio.netty.internal.NettyRequestExecutor.makeRequestListener(NettyRequestExecutor.java:189) ~[netty-nio-client-2.20.55.jar:na]
at io.netty.util.concurrent.DefaultPromise.notifyListener0(DefaultPromise.java:590) ~[netty-common-4.1.92.Final.jar:4.1.92.Final]
at io.netty.util.concurrent.DefaultPromise.notifyListenersNow(DefaultPromise.java:557) ~[netty-common-4.1.92.Final.jar:4.1.92.Final]
at io.netty.util.concurrent.DefaultPromise.access$200(DefaultPromise.java:35) ~[netty-common-4.1.92.Final.jar:4.1.92.Final]
at io.netty.util.concurrent.DefaultPromise$1.run(DefaultPromise.java:503) ~[netty-common-4.1.92.Final.jar:4.1.92.Final]
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174) ~[netty-common-4.1.92.Final.jar:4.1.92.Final]
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167) ~[netty-common-4.1.92.Final.jar:4.1.92.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470) ~[netty-common-4.1.92.Final.jar:4.1.92.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569) ~[netty-transport-4.1.92.Final.jar:4.1.92.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.92.Final.jar:4.1.92.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.92.Final.jar:4.1.92.Final]
… 1 common frames omitted
Caused by: java.util.concurrent.TimeoutException: Acquire operation took longer than 10000 milliseconds.
at software.amazon.awssdk.http.nio.netty.internal.HealthCheckedChannelPool.timeoutAcquire(HealthCheckedChannelPool.java:77) ~[netty-nio-client-2.20.55.jar:na]
at software.amazon.awssdk.http.nio.netty.internal.HealthCheckedChannelPool.lambda$acquire$0(HealthCheckedChannelPool.java:67) ~[netty-nio-client-2.20.55.jar:na]
at io.netty.util.concurrent.PromiseTask.runTask(PromiseTask.java:98) ~[netty-common-4.1.92.Final.jar:4.1.92.Final]
at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:153) ~[netty-common-4.1.92.Final.jar:4.1.92.Final]
… 7 common frames omitted
Please verify the followings:
There is a queue created in AWS SNS with name: HowToDoInJava
The AWS credentials or permissions are configured properly.
Double check the queue URL as defined in spring.cloud.aws.sqs.endpoint.
Thanks for reply, I haven’t configure SNS. My focus only to use sqs and IAM user accesskey,secretkey, endpoint of sqs setup correctly.
Queue name is enough? I dont see this spring.cloud.aws.sqs.endpoint.property in application.properties file could please rerun from your side once again
sqsSendOptions
.queue(“HowToDoInJava”)
.payload(message)
Yes, it is working fine. I tested again and without any code changes, it worked. The only change I made was that AWS key and secrets are now referred from environment properties.
And apologies for suggesting changes in SNS. I wanted to say SQS. Please make sure the queue exists there.
To verify that message reached in AWS SQS, use code in section 9.1. The message will not be deleted from AWS and you can verify it in aws console itself.
Many thanks. Apologies, I forgot to uncomment sqsAsyncClient in sqsconfig. Now it is working. Thank you
Hi ,
the contextLoad() test method in the application fails only when the io.awspring.cloud:spring-cloud-aws-starter-sqs is added as the dependency. any idea? i dont think any other dependency except the aws java sdk has the http clients in them.
Caused by: software.amazon.awssdk.core.exception.SdkClientException: Multiple HTTP implementations were found on the classpath. To avoid non-deterministic loading implementations, please explicitly provide an HTTP client via the client builders, set the software.amazon.awssdk.http.service.impl system property with the FQCN of the HTTP service to use as the default, or remove all but one HTTP implementation from the classpath. The multiple implementations found were: [software.amazon.awssdk.http.apache.ApacheSdkHttpService,software.amazon.awssdk.http.urlconnection.UrlConnectionSdkHttpService]