admin管理员组

文章数量:1122833

I have a Reactive JAVA Spring Boot application with R2DBC mysql with following configuration:

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

My Application has two workflow:

A. Generate data for processing - Uses 1 thread

  • This consumes message from SQS and use it to prepare data.

  • processMessage method is a reactive method which is processing message and generate data in reactive flow. Used .block as I have used Session Acknowledgement Mode as CLIENT_ACKNOWLEDGE

    myConsumerService.processMessage(message).block();

B. Process data - Uses 10 threads

  • A single thread is processing these 3 operations one after another.

  • Every MySQL operation is completed within two digit milliseconds.

  • Used following code to get records from 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();
         }
    }
    

I have used DEBUG logging mode for R2DBC(logging.level.io.r2dbc.pool=DEBUG) and it shows connection is acquired just before MySQL operation and released immediately after the MySQL operation.

Expected result : Application suppose to use maximum of 11 connections so allocated connections by the R2DBC connection should be 11.

Actual result : Logs shows 20 connections are allocated by the R2DBC connection pool.

Here is the log which I have observed : ConnectionPoolStats : Allocated : 20, Acquired : 1, Idle : 0, Pending : 9

For reference I have used following code to get ConnectionPoolStats:

 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.");
 }

Questions :

  1. Why all the connections shows as allocation as application doesn't required at any point of time?
  2. Is any probability where I lead to any unusual connection state?

本文标签: javaWhy R2DBC connection pool allocating MAX connections when not needed by the applicationStack Overflow