Reputation: 121
I am working on a Reactive Java Spring Boot application using R2DBC with MySQL. Below is the connection pool configuration I have set up:
spring.r2dbc.pool.enabled=true
spring.r2dbc.pool.initial-size=0
spring.r2dbc.pool.max-size=20
spring.r2dbc.pool.max-acquire-time=30s
spring.r2dbc.pool.max-idle-time=1m
Application Workflow Details:
A. Generate data for processing (Uses 1 thread)
This workflow consumes messages from SQS and processes them to generate data.
The processMessage method is reactive and generates data using a reactive flow.
I am using .block() in this case because I have configured Session Acknowledgement Mode as CLIENT_ACKNOWLEDGE:
myConsumerService.processMessage(message).block();
B. Process data (Uses 10 threads)
10 threads are used for processing data operations concurrently.
A single thread performs 3 MySQL operations one after another.
Each MySQL operation takes only a few milliseconds to complete.
The following code retrieves records for MySQL operations:
public class MyRepository {
private final R2dbcEntityTemplate template;
public MyRepository(R2dbcEntityTemplate template) {
this.template = template;
}
public Mono<MyEntity> getEntityById(Long id) {
return template.select(MyEntity.class)
.matching(Query.query(Criteria.where("id").is(id))).one();
}
}
Issue: Even though I have configured a pool with a maximum size of 20, I observe that the connection pool allocates 20 connections, which exceeds the expected value of 11. According to the logs, the connections are allocated just before MySQL operations and released immediately after, as expected.
Here are the relevant debug logs from the R2DBC connection pool (with logging level set to DEBUG):
ConnectionPoolStats : Allocated : 20, Acquired : 1, Idle : 0, Pending : 9
Expected Behavior: The application should use a maximum of 11 connections, with 1 thread dedicated to data generation and 10 threads dedicated to processing MySQL operations.
Actual Behavior: Despite the configuration, the logs show that the connection pool allocates 20 connections, leading to new connection requests being placed in a pending state, causing the following exception:
Caused by: io.r2dbc.spi.R2dbcTimeoutException: Connection acquisition timed out after 30000ms
Code to Retrieve Pool Metrics: I am using the following code to fetch connection pool metrics:
PoolMetrics metrics = connectionPool.getMetrics().orElse(null);
if (metrics != null) {
String connectionPoolStats = String.format("Allocated : %d, Acquired : %d, Idle : %d, Pending : %d",
metrics.allocatedSize(), metrics.acquiredSize(),
metrics.idleSize(), metrics.pendingAcquireSize());
logger.info("ConnectionPoolStats : {}", connectionPoolStats);
} else {
System.out.println("Connection Pool Metrics are not available.");
}
Question: Why is the R2DBC connection pool allocating 20 connections, and not adhering to the expected 11?
Upvotes: 1
Views: 63