美文网首页Druiddruid
Druid 监控实现原理

Druid 监控实现原理

作者: 晴天哥_王志 | 来源:发表于2022-02-14 21:59 被阅读0次

Druid监控功能

  • druid提供了丰富的监控功能,这篇文章主要分析下监控功能的实现原理。
  • 通过代理模式控制statement对象的访问。druid里的Statement、PreparedStatement、Connection等对象都通过代理模式访问。对应的druid的代理是StatementProxyImpl、PreparedStatementProxyImpl、ConnectionProxyImpl。
  • 通过filter过滤器链增加监控和日志功能。

Connection

  • Druid的连接对象PhysicalConnectionInfo的创建过程经过FilterChainImpl进行封装,核心是经过相关的Filter进行包装。
public abstract class DruidAbstractDataSource extends WrapperAdapter implements DruidAbstractDataSourceMBean, DataSource, DataSourceProxy, Serializable {

    public PhysicalConnectionInfo createPhysicalConnection() throws SQLException {
        String url = this.getUrl();
        Properties connectProperties = getConnectProperties();
        // 省略相关的代码
     
        try {
            // 创建物理链接
            conn = createPhysicalConnection(url, physicalConnectProperties);
            connectedNanos = System.nanoTime();

        } catch (SQLException ex) {
            throw ex;
        } catch (RuntimeException ex) {
            throw ex;
        } catch (Error ex) {
            throw ex;
        } finally {
            long nano = System.nanoTime() - connectStartNanos;
            createTimespan += nano;
            creatingCountUpdater.decrementAndGet(this);
        }
        // 创建PhysicalConnectionInfo
        return new PhysicalConnectionInfo(conn, connectStartNanos, connectedNanos, initedNanos, validatedNanos, variables, globalVariables);
    }


    public Connection createPhysicalConnection(String url, Properties info) throws SQLException {
        Connection conn;
        if (getProxyFilters().size() == 0) {
            conn = getDriver().connect(url, info);
        } else {
            // 通过FilterChainImpl进行装饰
            conn = new FilterChainImpl(this).connection_connect(info);
        }

        createCountUpdater.incrementAndGet(this);

        return conn;
    }
  • FilterChainImpl返回Connection对象,通过PhysicalConnectionInfo封装。
public class FilterChainImpl implements FilterChain {

    public ConnectionProxy connection_connect(Properties info) throws SQLException {
        // 通过Filter进行封装
        if (this.pos < filterSize) {
            return nextFilter()
                    .connection_connect(this, info);
        }

        Driver driver = dataSource.getRawDriver();
        String url = dataSource.getRawJdbcUrl();

        Connection nativeConnection = driver.connect(url, info);

        if (nativeConnection == null) {
            return null;
        }

        return new ConnectionProxyImpl(dataSource, nativeConnection, info, dataSource.createConnectionId());
    }
}
  • FilterChainImpl内部经过Filter进行封装,核心是通过Filter进行封装。
  • 在经过Filter封装前创建的时ConnectionProxyImpl对象,外层进行Filter的包装。
  • Connection的封装对象是ConnectionProxyImpl对象。

Statement

  • Druid的连接对象PreparedStatement的创建过程经过FilterChainImpl进行封装,核心是经过相关的Filter进行包装。
  • Druid的连接对象Statement的创建过程经过FilterChainImpl进行封装,核心是经过相关的Filter进行包装。
public class ConnectionProxyImpl extends WrapperProxyImpl implements ConnectionProxy {

    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        FilterChainImpl chain = createChain();
        // 通过FilterChainImpl获取prepareStatement
        PreparedStatement stmt = chain.connection_prepareStatement(this, sql);
        recycleFilterChain(chain);
        return stmt;
    }
}


public class FilterChainImpl implements FilterChain {

    @Override
    public PreparedStatementProxy connection_prepareStatement(
            ConnectionProxy connection,
            String sql,
            int autoGeneratedKeys) throws SQLException
    {
        // 通过FilterChainImpl获取prepareStatement
        if (this.pos < filterSize) {
            return nextFilter()
                    .connection_prepareStatement(this, connection, sql, autoGeneratedKeys);
        }

        PreparedStatement statement = connection.getRawObject().prepareStatement(sql, autoGeneratedKeys);

        if (statement == null) {
            return null;
        }
        // 返回 PreparedStatementProxyImpl
        return new PreparedStatementProxyImpl(connection, statement, sql, dataSource.createStatementId());
    }
}
  • FilterChainImpl内部经过Filter进行封装,核心是通过Filter进行封装。
  • 在经过Filter封装前创建的时PreparedStatementProxyImpl对象,外层进行Filter的包装。
  • PreparedStatement的代理对象是PreparedStatementProxyImpl。

Filter

  • Filter的所有相关接口在FilterAdapter都有默认实现,其他的具体的实现通过继承FilterAdapter后进行重写。

相关文章

网友评论

    本文标题:Druid 监控实现原理

    本文链接:https://www.haomeiwen.com/subject/rxztlrtx.html