WeChat searchBase in JavaLearn and progress together!

Druid:

The advent of connection pooling addresses the performance cost of creating database connections for each request and the increase in request response time in high concurrency scenarios. I used C3P0 connection pool before, but later I looked at Druid connection pool, which is a database connection pool for monitoring. Provides rich, multi-dimensional data monitoring compared to other connection pools.

Git git DruidGithub.com/alibaba/dru…


Druid initialization:

Description of common attribute nouns:

Url: specifies the database address. The driver type is specified by prefix. Username: indicates the database username. Password: indicates the database password. InitialSize: indicates the initialSize of the connection pooltestOnBorrow: Checks whether the connection is valid when it is obtainedtestOnReturn: checks whether the connection is valid when the connection is reclaimedtestWhileIdle: whether to detect when getting connection link connection idle for more than timeBetweenEvictionRunsMillis, more than the test connection timeBetweenEvictionRunsMillis: DestroyConnectionThread thread (effectiveness periodically connection) interval (Sleep) minEvictableIdleTimeMillis: connection thread pool minimum survival time again removeAbandoned: RemoveAbandonedTimeout: Indicates the maximum abandonedTimeout duration of an active thread. When the duration exceeds the threshold, the thread is discarded (unit: minute).logAbandoned: Disables the abandon connection. Whether to print logs. Filters: Requires druid-enabled filters. ConnectionInitSqls: mysql parameter to be set during connection. For example:setnames utf8mb4; AsyncInit: whether to initialize the connection pool asynchronously createScheduler: thread pool to initialize the connection validationQuery: SQL statement to verify whether the connection is valid keepAlive: whether to create an idle connection minIdle: Minimum number of idle connectionsCopy the code

In Spring, you can configure the data source and call the init method directly on the init-method property.

<bean name="readDataSource1" class="com.alibaba.druid.pool.DruidDataSource"  
 init-method="init" destroy-method="close">Copy the code

If initialization is not called manually, the first call to the DataSource’s getConnection method will trigger initialization logic to complete the initialization.

public DruidPooledConnection getConnection(long maxWaitMillis) throws SQLException { init(); if (filters.size() > 0) { FilterChainImpl filterChain = new FilterChainImpl(this); return filterChain.dataSource_connect(this, maxWaitMillis); } else { return getConnectionDirect(maxWaitMillis); }}Copy the code

The DruidDataSource initialization does a few things:

1. Process user-defined parameter values. Use jdbcUrl to check the database type (Mysql or Oracle), check whether the parameters are valid, initialize the configured filter, and load the driver.

2. Initialize the detector, such as the detector used to connect whether the connection is valid, and the detector used to query whether the statement is valid.

3. Instantiate a data source statistic object JdbcDataSourceStat. Druid connection pool is famous for monitoring, JdbcDataSourceStat is the data storage center!

4. Initialize three arrays to store database connections, discarded connections, and connections that are still alive after detection, and initialize database connections. Initialize three threads, namely the logging thread, generate a database connection, and detect if the connection times out.

DruidDataSource initializes several key points:

Initialize the connection pool

if(createScheduler ! = null && asyncInit) {for (int i = 0; i < initialSize; ++i) {
        submitCreateTask(true); }}else if(! asyncInit) { // init connectionswhile (poolingCount < initialSize) {
        try {
            PhysicalConnectionInfo pyConnectInfo = createPhysicalConnection();
            DruidConnectionHolder holder = new DruidConnectionHolder(this, pyConnectInfo);
            connections[poolingCount++] = holder;
        } catch (SQLException ex) {
            LOG.error("init datasource error, url: " + this.getUrl(), ex);
            if (initExceptionThrow) {
                connectError = ex;
                break;
            } else{ Thread.sleep(3000); }}}if(poolingCount > 0) { poolingPeak = poolingCount; poolingPeakTime = System.currentTimeMillis(); }}Copy the code

When createScheduler (thread pool), asyncInit (Boolean) is configured and asyncInit is true, asyncInit is initialized asynchronously or blocks the main thread until initialization is complete. PoolingCount specifies the current line pool size.

private void submitCreateTask(boolean initTask) { createTaskCount++; CreateConnectionTask task = new CreateConnectionTask(initTask);if(createTasks == null) {createTasks = new Long [8]; } boolean putted =false;
    for (int i = 0; i < createTasks.length; ++i) {
        if (createTasks[i] == 0) {
            createTasks[i] = task.taskId;
            putted = true;
            break; }}if(! Putted) {// When the createTasks array is full, expand it by 1.5 times the previous array size. long[] array = new long[createTasks.length * 3 / 2]; System.arraycopy(createTasks, 0, array, 0, createTasks.length); array[createTasks.length] = task.taskId; createTasks = array; } / / in the thread pool to perform this. CreateSchedulerFuture = createScheduler. Submit (task); }Copy the code

The createPhysicalConnection() method returns an object that holds the actual connection to the reference

The PhysicalConnectionInfo object that creates a database connection based on the configured property. Initialize the connection after it is created (whether to commit automatically, set transaction isolation level, pre-execute

ConnectionInitSqls data amount setting statement
), validity check, execute the configured SQL statement.

Generate the PhysicalConnetionInfo and DruidDataSource returns

DruidConnectionHolder object (the object of the actual connection pool operation), placed in the connection pool array until the connection pool size equals
InitialSize.

If asyncInit is set to false, the connection is created through a while loop with the following core code

while (poolingCount < initialSize) {
    try {
        PhysicalConnectionInfo pyConnectInfo = createPhysicalConnection();
        DruidConnectionHolder holder = new DruidConnectionHolder(this, pyConnectInfo);
        connections[poolingCount++] = holder;
    } catch (SQLException ex) {
        LOG.error("init datasource error, url: " + this.getUrl(), ex);
        if (initExceptionThrow) {
            connectError = ex;
            break;
        } else{ Thread.sleep(3000); }}}Copy the code

The logic is consistent with the thread pool pattern.


This completes the Druid thread pool, general parameter configuration, and initialization of the specified number of connections. The creation of three threads remains for the next chapter


                                                           

(Scan the following public account)



Note: Based on the level limit, the document is only for their own improvement, please comment on the discrepancy. (Unauthorized transfer prohibited)