Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Connection timeouts with HikariCP

I have a Spring Boot (v2.0.8) application which makes use of a HikariCP (v2.7.9) Pool (connecting to MariaDB) configured with:

minimumIdle: 1
maximumPoolSize: 10
leakDetectionThreshold: 30000

The issue is that our production component, once every few weeks, is repeatedly throwing SQLTransientConnectionException " Connection is not available, request timed out after 30000ms...". The issue is that it never recovers from this and consistently throws the exception. A restart of the componnent is therefore required.

From looking at the HikariPool source code, it would seem that this is happening because every time it is calling connectionBag.borrow(timeout, MILLISECONDS) the poolEntry is null and hence throws the timeout Exception. For it to be null, the connection pool must have no free entries i.e. all PoolEntry in the sharedList are marked IN_USE.

I am not sure why the component would not recover from this since eventually I would expect a PoolEntry to be marked NOT_IN_USE and this would break the repeated Exceptions.

Possible scenarios I can think of:

  1. All entries are IN_USE and the DB goes down temporarily. I would expect Exceptions to be thrown for the in-flight queries. Perhaps at this point the PoolEntry status is never reset and therefore is stuck at IN_USE. In this case I would have thought if an Exception is thrown the status is changed so that the connection can cleared from the pool. Can anyone confirm if this is the case?

  2. A flood of REST requests are made to the component which in turn require DB queries to be executed. This fills the connection pool and therefore subsequent requests timeout waiting for previous requests to complete. This makes sense however I would expect the component to recover once the requests complete, which it is not.

Does anyone have an idea of what might be the issue here? I have tried configuring the various timeouts that are in the Hikari documentation but have had no luck diagnosing / resolving this issue. Any help would be appreciated.

Thanks!

like image 631
sam Avatar asked Jun 12 '19 19:06

sam


People also ask

How does HikariCP connection pool work?

"HikariCP is solid high-performance JDBC connection pool. A connection pool is a cache of database connections maintained so that the connections can be reused when future requests to the database are required. Connection pools may significantly reduce the overall resource usage." - You can find out more here.

What is connection timeout?

A server connection timeout means that a server is taking too long to reply to a data request made from another device. Timeouts are not a reply message: they show up when there isn't a reply and a server request is not fulfilled in a predetermined length of time.

What is idle timeout Hikari?

// idleTimeout is the maximum amount of time a connection can sit in the pool. Connections that. // sit idle for this many milliseconds are retried if minimumIdle is exceeded. config. setIdleTimeout(600000); // 10 minutes.


1 Answers

Scenario 2 is most likely what is happening. I ran into the same issue when using it with cloud dataflow and receiving a large amount of connection requests. The only solution I found was to play with the config to find a combination that worked for my use case.

I'll leave you my code that works for 50-100 requests per second and wish you luck.

private static DataSource pool;
final HikariConfig config = new HikariConfig();
config.setMinimumIdle(5);
config.setMaximumPoolSize(50);
config.setConnectionTimeout(10000);
config.setIdleTimeout(600000);
config.setMaxLifetime(1800000);
config.setJdbcUrl(JDBC_URL);
config.setUsername(JDBC_USER);
config.setPassword(JDBC_PASS);

pool = new HikariDataSource(config);
like image 53
R Wri Avatar answered Sep 18 '22 13:09

R Wri