蓝凌EKP产品:扩展Druid 数据源KmssDruidDataSource在企业级数据源初始化与连接监控实践

单纯的DruidDataSource 不是拿来即用,在很多企业级 Java 项目中,我们需要扩展,今天主要介绍一下我们功能强大的扩展的KmssDruidDataSource,他是如何解耦,可扩展的实现我们适配各个数据库的监控 ,现在我们完整介绍它的设计目的与实现思路。

一、KmssDruidDataSource 是做什么的?

KmssDruidDataSource 是一个 继承自 DruidDataSource 的增强型数据源实现,主要解决以下问题:

  • 不同数据库方言下的连接校验差异

  • validationQuery 遗漏导致的断链不可恢复

  • JDBC 连接泄露难以定位

  • 多启动方式(JDBC / JNDI)下的初始化兼容

一句话概括:

它不是替代 Druid,而是让 Druid 更适合企业长期运行。

二、整体类结构与生命周期位置

复制代码
public class KmssDruidDataSource extends DruidDataSource
        implements InitializingBean

关键点说明

  • 继承 DruidDataSource:完全复用 Druid 能力

  • 实现 InitializingBean

    Spring 完成属性注入后、数据源真正初始化前 插入增强逻辑

这是非常典型的 Spring + 中间件增强模式

三、启用条件控制:不是所有场景都生效

复制代码
private boolean checkNecessary() {
    return KMSS_TYPE_JDBC.equals(KMSS_CONNECTION_TYPE)
        && "druidDataSource".equalsIgnoreCase(
            ResourceUtil.getKmssConfigString("kmss.jdbc.datasource"));
}

为什么要做条件判断?

在真实项目中,往往存在:

  • JNDI 数据源

  • 多数据源并存

  • 历史系统混合配置

增强逻辑必须是"可控的",否则很容易引入隐性风险。

四、初始化阶段的核心增强逻辑

增强逻辑集中在 afterPropertiesSet() 中。

4.1 自动识别数据库方言

当未显式配置 validationQuery 时,系统会:

  1. 读取 hibernate.dialect

  2. 使用 ServiceLoader 加载 IDataBaseAdapter

  3. 找到匹配的数据库适配器

    ServiceLoader<IDataBaseAdapter> loaders =
    ServiceLoader.load(IDataBaseAdapter.class);

设计意义

  • 解耦数据库差异

  • 避免硬编码 SQL

  • 支持扩展更多数据库类型


4.2 自动设置 validationQuery(兜底机制)

复制代码
setValidationQuery(adapter.getConnectionTestQuery());

典型效果:

数据库 校验 SQL
Oracle select 1 from dual
MySQL select 1

如果识别失败,会输出 明确的 WARN 日志,提示人工配置。

这是一个非常务实的设计

能自动就自动,不能自动就明确告警。

4.3 HibernateContext 数据库适配器注入

复制代码
HibernateContext.setDataBaseAdapter(dbAdapter);

这一步不仅影响连接校验,还会影响:

  • SQL 生成

  • 分页语法

  • 数据库函数适配

说明 KmssDruidDataSource 在系统中承担的是数据库上下文初始化角色

五、Druid 统计与日志增强

当配置开启:

复制代码
kmss.jdbc.stat.enabled=true

初始化阶段会:

复制代码
addFilters("stat");
super.filters.add(new KmssDruidDataSourceLogFilter());

带来的能力

  • SQL 执行统计

  • 活跃连接数监控

  • 自定义 JDBC 日志输出

为后续性能分析和问题定位打下基础。

六、连接占用监控:最有工程价值的设计

6.1 设计动机

现实中的 JDBC 问题往往是:

  • 连接没关

  • 事务太长

  • 线程被阻塞

但日志里只剩一句:

获取数据库连接超时


6.2 实现方式

KmssDruidDataSource 启动一个定时任务:

  • 每 60 秒扫描一次

  • 找出占用超过 60 秒的连接

  • Dump 持有连接的线程堆栈

    info.dumpActiveConnectionStackTrace(60000);

6.3 实际价值

  • 不依赖问题复现

  • 不需要 JVM 全量 dump

  • 直接定位"是谁没释放连接"

对于 OA、流程、审批类系统尤为重要。

七、JNDI 场景下的 init 兼容处理

复制代码
@Override
public void init() throws SQLException {
    if (checkNecessary()) {
        super.init();
    }
}

解决的问题

  • 容器托管数据源提前初始化

  • 非目标场景误触发 Druid init

  • 启动阶段异常

这是典型的 企业级启动兼容代码

八、KmssDruidDataSource 的设计特点总结

优点

  • 启用条件明确,不侵入

  • 数据库方言解耦

  • 自动兜底 + 明确告警

  • 具备连接级可观测能力

适用场景

  • 多数据库支持系统

  • 长事务 / 流程型系统

  • 对稳定性要求高的企业应用

九、结语

扩展KmssDruidDataSource 主要有如下功能:

  • 出问题时,你能不能快速定位

  • 跑久了,系统会不会慢慢失血

相关推荐
瀚高PG实验室4 分钟前
数据库日志过大
数据库·瀚高数据库
2401_857683547 分钟前
使用Kivy开发跨平台的移动应用
jvm·数据库·python
yangSnowy13 分钟前
MySQL 分布式锁实现方案
数据库·分布式·mysql
倔强的石头10616 分钟前
关系数据库替换用金仓:从 Oracle 到 KingbaseES 的迁移实战
数据库·oracle·kingbase
Leo.yuan18 分钟前
制造业五大模式解析:OEM、ODM、OBM、JDM、CMT
大数据·数据库·信息可视化
铬仁18 分钟前
kettle 9.2 连接达梦DM Database Server 64 V8
数据库·etl
松涛和鸣25 分钟前
69、Linux字符设备驱动实战
linux·服务器·网络·arm开发·数据库·驱动开发
2501_9419820527 分钟前
企微自动化开发:安全与效率的平衡术
数据库·mysql·企业微信
阿里-于怀28 分钟前
Kubernetes 官方再出公告,强调立即迁移 Ingress NGINX
java·大数据·数据库·ingress nginx
玄同76534 分钟前
数据库全解析:从关系型到向量数据库,LLM 开发中的选型指南
数据库·人工智能·知识图谱·milvus·知识库·向量数据库·rag