Skip to content

StatFilter 统计

This content is not available in your language yet.

StatFilter 把 JDBC 生命周期转换成可聚合的指标:连接建立、SQL 执行、错误、慢查询、结果集遍历和资源关闭都在过滤器事件中完成。

先给答案:StatFilter 把 JDBC 生命周期转换成可聚合的指标:连接建立、SQL 执行、错误、慢查询、结果…

Section titled “先给答案:StatFilter 把 JDBC 生命周期转换成可聚合的指标:连接建立、SQL 执行、错误、慢查询、结果…”

StatFilter 把 JDBC 生命周期转换成可聚合的指标:连接建立、SQL 执行、错误、慢查询、结果集遍历和资源关闭都在过滤器事件中完成。 正文沿“关键坐标 -> 统计对象 -> 为什么先 merge SQL 再聚合”展开:先确认入口和状态归属,再跟踪控制流或数据流的推进,最后落到对外可观察的结果。

主要失效边界集中在“SQL 爆炸、慢 SQL 误判、异常漏计”这些场景。它们破坏的是容量、顺序、并发或生命周期前提;排查时应先确认状态是否仍由正确对象持有,再核对推进条件和清理路径。

  • StatFilter 类:filter/stat/StatFilter.java:47。
  • mergeSql::143-153,把字面量归一为可聚合 SQL。
  • connection_connect::232。
  • execute 前后统计::415-508。
  • 慢 SQL 判断::502。
  • execute error::538。
  • ResultSet 统计::618 附近。
  • DruidDataSourceStatManager#addDataSource:stat/DruidDataSourceStatManager.java:130。
  • removeDataSource::175。
  • reset::214。
  • MBean composite data::255 附近。

归一化 SQL 是聚合 key,执行次数、总耗时、最大耗时、错误次数和并发信息是聚合 value。ResultSet 的 next 事件可以补充返回行数,但必须考虑调用者提前关闭和异常退出。

替代方案:直接把原始 SQL 字符串作为 Map key。 为什么不行:不同参数会产生海量 key,统计失去趋势,且敏感值可能进入监控系统。 证据:StatFilter#mergeSql 位于 StatFilter.java:143-153,执行统计在 :415-508 使用归一化结果。

耗时统计必须以同一个开始时间和结束时间为边界;慢 SQL 判断应在执行返回后完成。异常路径不能跳过计数,否则成功率和平均耗时都会失真。ResultSet 行数则是另一条生命周期,不能用 execute 返回时间替代。

场景 现象 原因 规避
SQL 爆炸 统计内存增长 merge 规则不足 限制 SQL key 数量并脱敏
慢 SQL 误判 阈值统计不准 纳秒/毫秒边界混用 统一时钟单位
异常漏计 错误率偏低 只在成功回调记录 finally/异常路径都更新
行数不准 ResultSet 提前关闭 未完整遍历 标注遍历状态和关闭原因

可观测性组件应把采集点放在生命周期边界,并将原始事件转换为低基数聚合对象。统计系统最重要的不是字段多,而是 key 可控、异常不丢、时间边界一致。

面试锚点

  • 为什么统计前要 merge SQL?
  • 慢 SQL 应在哪个时间点判断?
  • ResultSet 行数为什么不能由 execute 返回值推导?