【Druid源码阅读】10. 过滤器工作原理

11 篇文章 0 订阅

昨天以 StatFilter 分析了责任链模式,今天还以 StatFilter 来举例。

StatFilter 就是用来统计数据,用来支撑 Druid 监控的。

其实大概看一下 StatFilter 的结构,可以看到有很多 public 方法,第一个参数是 FilterChain,并且代码实现都是使用调用过滤器的同名方法,

过滤方法有很多,除了昨天介绍的 dataSource_getConnection,再举个例子:

@Override
public void connection_commit(FilterChain chain, ConnectionProxy connection) throws SQLException {
    // 调用过滤器链的下一个节点的 connection_commit 方法,一层层调用下去,直到最后一个
    chain.connection_commit(connection);

    // 从过滤器链中取出 DataSource,再从中取出 DataSourceStat
    JdbcDataSourceStat dataSourceStat = chain.getDataSource().getDataSourceStat();
    // 对操作计数 commitCount + 1
    dataSourceStat.getConnectionStat().incrementConnectionCommitCount();
}

public void incrementConnectionCommitCount() {
    commitCount.incrementAndGet();
}

从上面的代码中可以看到,最终统计数据是存储在 JdbcDataSourceStat 中的。

public interface DataSourceProxy {

    JdbcDataSourceStat getDataSourceStat();

...

前面我们分析了那么长时间的 DruidDataSource 类就是 DataSourceProxy 接口的实现类之一。

可以看到给 dataSourceStat 赋值的操作有3处,并且代码行数差的不多:

这不又回到了 init 方法中了吗?

统计数据都是怎么保存到呢,到 JdbcDataSourceStat 类中一探究竟:

public class JdbcDataSourceStat implements JdbcDataSourceStatMBean {

    private final static Log                                    LOG                     = LogFactory.getLog(JdbcDataSourceStat.class);

    private final String                                        name;
    private final String                                        url;
    private String                                              dbType;

    private final JdbcConnectionStat                            connectionStat          = new JdbcConnectionStat();
    private final JdbcResultSetStat                             resultSetStat           = new JdbcResultSetStat();
    private final JdbcStatementStat                             statementStat           = new JdbcStatementStat();

    private int                                                 maxSqlSize              = 1000;

    private ReentrantReadWriteLock                              lock                    = new ReentrantReadWriteLock();
    private final LinkedHashMap<String, JdbcSqlStat>            sqlStatMap;

    private final AtomicLong                                    skipSqlCount            = new AtomicLong();

    private final Histogram                                     connectionHoldHistogram = new Histogram(new long[] { //
                                                                                                        //
            1, 10, 100, 1000, 10 * 1000, //
            100 * 1000, 1000 * 1000
                                                                                                        //
                                                                                                        });

    private final ConcurrentMap<Long, JdbcConnectionStat.Entry> connections             = new ConcurrentHashMap<Long, JdbcConnectionStat.Entry>(
                                                                                                                                                16,
                                                                                                                                                0.75f,
                                                                                                                                                1);

    private final AtomicLong                                    clobOpenCount           = new AtomicLong();
    private final AtomicLong                                    blobOpenCount           = new AtomicLong();
    private final AtomicLong                                    keepAliveCheckCount     = new AtomicLong();

    private boolean                                             resetStatEnable         = true;

    private static JdbcDataSourceStat                           global;

...

这里面定义的属性分了几大类:

  • 像 JdbcConnectionStat、JdbcResultSetStat、JdbcStatementStat 又封装了一层针对特定场景的对象;
  • AtomicLong 类型的原子类,用于统计次数;
  • ...

最后再搜索一下 DruidDataSource#getDataSourceStat() 方法被调用的地方,大部分是在 StatFilter 中被调用时更新统计数据使用的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
druid java.lang.InterruptedException是指在使用druid连接池时,可能会出现的异常情况。具体而言,当在使用Druid连接池的过程中,线程被中断或者发生其他中断相关的异常时,就会抛出java.lang.InterruptedException异常。这个异常通常是由于线程在等待或执行任务时被中断所引起的。在Druid连接池的代码中,可以看到相关的异常信息,比如在DruidPooledConnection类的close方法中,可能会抛出这个异常。同样,在DruidDataSource类的recycle方法中也有可能出现这个异常。在处理这个异常时,可以根据具体的业务需求来进行相应的处理,例如进行错误日志记录、资源清理等。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [druid出现 java.lang.NoClassDefFoundError orgapachelog4j.md](https://download.csdn.net/download/xiao8898081/19776337)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Druid出现DruidDataSource - recyle error - recyle error java.lang.InterruptedException: null异常排查...](https://blog.csdn.net/weixin_39643189/article/details/114358921)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值