preface

HikariCP is the default database connection pool for SpringBoot2 and is touted as the fastest connection pool.

Image source: github.com/brettwooldr…

1. Basic Concepts

DataSource

DataSource inherits the Wrapper and CommonDataSource interfaces.

  • Wrapper: the current DataSource, if a proxy implementation, provides the ability to get the target instance. Unwrap gets the target instance. IsWrapperFor checks whether it can get the target instance of the specified Class.
public interface Wrapper { <T> T unwrap(java.lang.Class<T> iface) throws java.sql.SQLException; boolean isWrapperFor(java.lang.Class<? > iface) throws java.sql.SQLException; }Copy the code
  • CommonDataSource: Obtains Logger/PrintWriter for outputting logs and sets the database timeout period.
public interface CommonDataSource {
    java.io.PrintWriter getLogWriter() throws SQLException;
    void setLogWriter(java.io.PrintWriter out) throws SQLException;
    void setLoginTimeout(int seconds) throws SQLException;
    int getLoginTimeout() throws SQLException;
    public Logger getParentLogger() throws SQLFeatureNotSupportedException;
}
Copy the code
  • DataSource: Obtains the Connection.
public interface DataSource  extends CommonDataSource, Wrapper {
  Connection getConnection() throws SQLException;
  Connection getConnection(String username, String password)
    throws SQLException;
}
Copy the code

HikariConfig

HikariConfig saves all connection pool configurations, implements the HikariConfigMXBean interface, and some configurations can be changed using the JMX runtime. The core configuration is described in section 2.

HikariDataSource

Operation HikariPool to obtain the connection. You can see that HikariDataSource has two HikariPool member variables.

  • FastPathPool: Final modifier, determined at construction time. If null is used with a no-parameter construct, the same as pool is used with a parameter construct.
  • Pool: volatile modifier. A no-parameter construct does not set a pool. A pool is constructed on getConnection, as with fastPathPool.

This is probably because the pool volatile modifiers cause every read to be loaded from main memory and every write to be written back to main memory, which is worse than fastPathPool without volatile modifiers.

public class HikariDataSource extends HikariConfig implements DataSource, Closeable { private final AtomicBoolean isShutdown = new AtomicBoolean(); private final HikariPool fastPathPool; private volatile HikariPool pool; public HikariDataSource() { super(); fastPathPool = null; } public HikariDataSource(HikariConfig configuration) { configuration.validate(); configuration.copyStateTo(this); pool = fastPathPool = new HikariPool(this); this.seal(); }}Copy the code

PoolBase

PoolBase is the parent class of HikariPool. It is responsible for operating on the actual DataSource to get a Connection and setting some properties of the Connection.

abstract class PoolBase {
	// DriverDataSource
	private DataSource dataSource;
}
Copy the code

DriverDataSource

DriverDataSource implements the DataSource interface and uses java.sql.Driver to obtain a Connection.

public final class DriverDataSource implements DataSource {
   private Driver driver;
}
Copy the code

HikariPool

This is the primary connection pool class that provides the basic

pooling behavior for HikariCP.

The main connection pooling class, which provides basic pooling behavior for HikariCP.

public final class HikariPool extends PoolBase implements HikariPoolMXBean, IBagStateListener {public volatile int poolState; Private Final PoolEntryCreator = new PoolEntryCreator(null); private final PoolEntryCreator postFillPoolEntryCreator = new PoolEntryCreator("After adding "); / / addConnectionExecutor blocked waiting queue read-only view private final Collection < Runnable > addConnectionQueueReadOnlyView; Private Final ThreadPoolExecutor addConnectionExecutor; Private final ThreadPoolExecutor closeConnectionExecutor; LinkedBlockingQueue Private final ConcurrentBag<PoolEntry> connectionBag; // Create ProxyLeakTaskFactory (ProxyLeakTask is used to detect leaks) Private Final ProxyLeakTaskFactory leakTaskFactory; // Suspend and restore the encapsulated semaphores for the connection pool. / / thread pool, HouseKeeper task HouseKeeper to maintain the minimum number of connections private final ScheduledExecutorService houseKeepingExecutorService; }Copy the code

ConcurrentBag

ConcurrentBag is a concurrency class designed by HikariCP for connection pooling.

Public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseable {// Save all elements private final CopyOnWriteArrayList<T> sharedList; Private final Boolean weakThreadLocals; Private final ThreadLocal<List<Object>> threadList; IBagStateListener (HikariPool) private final IBagStateListener listener; // Waiters count private final AtomicInteger; Private final SynchronousQueue<T> handoffQueue; Public interface IBagStateListener {// waiting indicates that several elements need to be added. Void addBagItem(int waiting); } public interface IConcurrentBagEntry {int STATE_NOT_IN_USE = 0; int STATE_IN_USE = 1; int STATE_REMOVED = -1; int STATE_RESERVED = -2; boolean compareAndSet(int expectState, int newState); void setState(int newState); int getState(); }}Copy the code

PoolEntry

PoolEntry actually has an instance of Connection that implements the IConcurrentBagEntry interface and can be put into a ConcurrentBag container.

final class PoolEntry implements IConcurrentBagEntry {
   Connection connection;
   private final HikariPool hikariPool;
}
Copy the code

Second, core configuration

The HikariConfig member variables cover all configurations of the Hikari connection pool.

Public class HikariConfigMXBean {// HikariConfigMXBean; // HikariConfigMXBean; Default 30s private Volatile Long connectionTimeout; // Timeout period for verifying connection validity. Default value: 5s Private Volatile Long validationTimeout; // Connection idle time. The value takes effect when the minimum number of connections is less than the maximum number of connections. The default value is 10min. // Connection leak detection duration, 0 by default, cannot exceed maxLifetime private Volatile Long leakDetectionThreshold; // The maximum connection lifetime, 30 minutes by default, must be shorter than the database wait_timeout. // The maximum number of connections is default 10 private volatile int maxPoolSize; // Minimum connection number default 10 private volatile int minIdle; Immutable / / / / runtime initialize check ok with the database connection timeout, 1, the default is 0 representative don't initialize private long initializationFailTimeout; Private String connectionInitSql; private String connectionInitSql; Private String connectionTestQuery; private String connectionTestQuery; True private Boolean isAutoCommit; False private Boolean isReadOnly; Private Boolean isRegisterMbeans; private Boolean isRegisterMbeans; // Whether connection pool suspension is allowed. Default: No private Boolean isAllowPoolSuspension;Copy the code

conclusion

  • Master the relationship between classes of HikariCP.
  • Comb core configuration.

subsequent

HikariCP contains many micro-optimizations that individually are barely measurable, but together combine as a boost to overall performance. Some of these optimizations are measured in fractions of a millisecond amortized over millions of invocations.

HikariCP contains a number of micro-optimizations that are almost impossible to measure individually, but can be combined to improve overall performance. Some of these optimizations are amortized in millions of milliseconds.

In the next chapter, learn about HikariCP’s ConcurrentBag (analogous to a traditional blocking queue) and FastList (analogous to an ArrayList).