当前位置: 首页 > ds >正文

Druid连接池使用和源码分析

Druid是阿里巴巴开源的一款高性能数据库连接池,它不仅拥有出色的性能,还提供了强大的监控和防御SQL注入功能。本文将从使用方法、配置参数、架构设计和源码分析四个方面深入探讨Druid,帮助你全面掌握这一国产优秀开源组件。

一、Druid连接池的使用方法与配置

1. 添加依赖

Maven项目中添加以下依赖:

<dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version>
</dependency>

2. 基本配置与使用

以下是一个基本的Druid连接池配置示例:

import com.alibaba.druid.pool.DruidDataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;public class DruidExample {public static void main(String[] args) {// 创建数据源DruidDataSource dataSource = new DruidDataSource();// 配置数据库连接信息dataSource.setUrl("jdbc:mysql://localhost:3306/mydatabase");dataSource.setUsername("root");dataSource.setPassword("password");// 配置连接池参数dataSource.setInitialSize(5);           // 初始化连接数dataSource.setMaxActive(20);            // 最大连接数dataSource.setMinIdle(5);               // 最小空闲连接数dataSource.setMaxWait(60000);           // 获取连接的最大等待时间(毫秒)dataSource.setTimeBetweenEvictionRunsMillis(60000); // 配置间隔多久才进行一次检测,检测需要关闭的空闲连接dataSource.setMinEvictableIdleTimeMillis(300000);   // 配置一个连接在池中最小生存的时间dataSource.setValidationQuery("SELECT 1");          // 验证连接有效性的SQLdataSource.setTestWhileIdle(true);                  // 连接空闲时是否进行有效性检测dataSource.setTestOnBorrow(false);                  // 获取连接时是否进行有效性检测dataSource.setTestOnReturn(false);                  // 归还连接时是否进行有效性检测try (Connection connection = dataSource.getConnection();Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery("SELECT * FROM users")) {while (resultSet.next()) {System.out.println("ID: " + resultSet.getInt("id") + ", Name: " + resultSet.getString("name"));}} catch (Exception e) {e.printStackTrace();} finally {// 关闭数据源dataSource.close();}}
}

3. 常用配置参数说明

参数名默认值说明
url-数据库连接URL
username-数据库用户名
password-数据库密码
initialSize0初始化连接数
maxActive8最大连接数
minIdle0最小空闲连接数
maxWait-1获取连接的最大等待时间(毫秒),-1表示无限等待
timeBetweenEvictionRunsMillis60000配置间隔多久才进行一次检测,检测需要关闭的空闲连接
minEvictableIdleTimeMillis300000配置一个连接在池中最小生存的时间
validationQuery-验证连接有效性的SQL
testWhileIdletrue连接空闲时是否进行有效性检测
testOnBorrowfalse获取连接时是否进行有效性检测
testOnReturnfalse归还连接时是否进行有效性检测
poolPreparedStatementsfalse是否缓存PreparedStatement
maxPoolPreparedStatementPerConnectionSize-1每个连接最多缓存的PreparedStatement数量
filters-配置监控统计拦截的filters,如stat,wall,log4j

二、Druid连接池架构设计

Druid连接池的架构设计融合了高性能与丰富的功能特性,其核心组件包括:

  1. DruidDataSource:数据源实现类,继承自javax.sql.DataSource,作为连接池的入口点。

  2. DruidConnectionHolder:连接持有者,包装了实际的数据库连接,并存储连接的元信息。

  3. DruidPooledConnection:代理连接类,实现了对实际数据库连接的代理,负责连接的生命周期管理。

  4. DruidAbstractDataSource:抽象数据源类,定义了数据源的基本行为和属性。

  5. DruidConnectionPool:连接池的核心实现,负责连接的创建、获取、归还和销毁。

  6. DestroyTask:后台线程,负责监控空闲连接和超时连接,定期清理和维护连接池。

  7. FilterChainManager:过滤器链管理器,负责管理和执行各种过滤器,提供监控、防御SQL注入等功能。

Druid连接池架构组件关系图:

┌─────────────────────┐
│    DruidDataSource   │
└───────────┬─────────┘│▼
┌─────────────────────┐
│   DruidConnectionPool │
├─────────────────────┤
│ - CreateConnectionThread │
│ - DestroyTask Thread    │
│ - DruidConnectionHolder List │
└───────────┬─────────┘│▼
┌─────────────────────┐
│  DruidPooledConnection │
├─────────────────────┤
│ - FilterChain       │
└───────────┬─────────┘│▼
┌─────────────────────┐
│  FilterChainManager  │
├─────────────────────┤
│ - StatFilter        │
│ - WallFilter        │
│ - LogFilter         │
└─────────────────────┘

三、Druid连接池源码分析

1. 初始化过程

Druid连接池的初始化过程主要在DruidDataSource类中完成:

public class DruidDataSource extends DruidAbstractDataSource implements DruidDataSourceMBean, Referenceable, Closeable {// 初始化方法public void init() throws SQLException {if (inited) {return;}// 获取锁,确保单线程初始化final ReentrantLock lock = this.lock;lock.lock();try {// 再次检查是否已初始化if (inited) {return;}// 初始化配置initConfig();// 初始化连接池initStat();initConnections();initCreateThread();initDestroyThread();// 标记为已初始化inited = true;} finally {lock.unlock();}}
}

关键步骤包括:

  • 配置参数的初始化和验证
  • 创建初始连接
  • 启动创建连接和销毁连接的后台线程

2. 连接获取过程

当调用getConnection()方法时,实际执行的是DruidDataSourcegetConnection()方法:

public Connection 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);}
}

连接获取的核心逻辑:

  • 如果配置了过滤器,创建过滤链并通过过滤链获取连接
  • 否则直接从连接池获取连接
  • 处理连接超时和连接有效性验证

3. 连接池管理

Druid通过DestroyTask线程定期清理和维护连接池:

public class DestroyTask implements Runnable {@Overridepublic void run() {shrink(true, keepAlive);if (isRemoveAbandoned()) {removeAbandoned();}}
}

DestroyTask线程的主要职责:

  • 收缩连接池,关闭空闲时间超过阈值的连接
  • 移除超时的废弃连接,防止内存泄漏

4. 过滤器机制

Druid的过滤器机制是其一大特色,通过过滤器可以实现监控、防御SQL注入等功能:

public interface Filter {// 连接相关方法Connection proxyConnection(FilterChain chain, DruidConnectionHolder holder) throws SQLException;// Statement相关方法Statement proxyStatement(FilterChain chain, Statement statement) throws SQLException;// PreparedStatement相关方法PreparedStatement proxyPrepareStatement(FilterChain chain, String sql) throws SQLException;// ResultSet相关方法ResultSet proxyResultSet(FilterChain chain, ResultSet resultSet) throws SQLException;
}

常用的过滤器:

  • StatFilter:统计监控过滤器,收集SQL执行性能数据
  • WallFilter:防御SQL注入过滤器,提供SQL防火墙功能
  • LogFilter:日志过滤器,记录SQL执行日志

四、Druid连接池的特色功能

1. 监控统计功能

Druid提供了强大的监控统计功能,可以通过配置开启:

// 配置监控统计拦截的filters
dataSource.setFilters("stat");// 配置StatFilter
StatFilter statFilter = new StatFilter();
statFilter.setSlowSqlMillis(1000); // 慢SQL定义,超过1秒的SQL为慢SQL
statFilter.setLogSlowSql(true);    // 记录慢SQL
dataSource.getProxyFilters().add(statFilter);

通过Druid的监控界面,可以查看:

  • SQL执行次数和执行时间统计
  • 连接池状态监控
  • 慢SQL日志
  • 并发连接监控

2. SQL防火墙功能

通过配置WallFilter,可以防御SQL注入攻击:

// 配置WallFilter
WallConfig wallConfig = new WallConfig();
wallConfig.setMultiStatementAllow(true); // 允许批量SQL
wallConfig.setNoneBaseStatementAllow(true); // 允许非基本语句WallFilter wallFilter = new WallFilter();
wallFilter.setConfig(wallConfig);
dataSource.getProxyFilters().add(wallFilter);

3. 配置加密功能

Druid支持数据库密码加密,保护敏感信息:

// 生成加密密码
String password = "your_password";
String[] arr = ConfigTools.genKeyPair(512);
String publicKey = arr[0];
String privateKey = arr[1];
String encryptedPassword = ConfigTools.encrypt(privateKey, password);// 配置加密密码
dataSource.setPassword(encryptedPassword);
dataSource.setConnectionProperties("config.decrypt=true;config.decrypt.key=" + publicKey);

五、总结

Druid连接池凭借其高性能、丰富的功能和良好的扩展性,成为了企业级Java应用的理想选择。通过深入理解其使用方法、配置参数、架构设计和源码实现,我们可以更好地在项目中应用和优化Druid,提高数据库访问性能和安全性。

主要关键点:

  • 使用简单:通过DruidDataSource配置连接池参数,获取数据库连接
  • 配置灵活:提供丰富的配置参数,满足各种场景需求
  • 功能强大:内置监控统计、SQL防火墙、连接池管理等功能
  • 架构优雅:采用过滤器链设计,便于功能扩展
  • 源码精妙:深入学习其源码可以了解到许多高性能编程和安全防御技巧

在实际项目中,建议根据应用的负载特性和安全需求,合理调整Druid的配置参数,并充分利用其监控和安全功能,保障系统的稳定运行。

http://www.xdnf.cn/news/9490.html

相关文章:

  • 为Windows用户量身定制的监控方案
  • 通过 API 获取 1688 平台订单接口的技术实现
  • LeetCode 118 题解--杨辉三角
  • 软考 系统架构设计师系列知识点之杂项集萃(77)
  • 1435系列信号发生器
  • 2025年上半年软考系统架构设计师--案例分析试题与答案
  • python 生成复杂表格,自动分页等功能
  • 自动驾驶规划控制教程——不确定环境下的决策规划
  • 火柴INIBOX矿机实测850M算力即将改写Initverse挖矿规则
  • 模型可信度
  • 缩量资金迁徙下的短期博弈
  • phpstudy(1) -- 记录
  • Orpheus-TTS:AI文本转语音,免费好用的TTS系统
  • 第二十二章:数据治理之数据价值:数据价值知多少
  • 远程模块“破壁”指南:打破空间限制,让控制“无界”!
  • 解析pod
  • MySQL推出全新Hypergraph优化器,正式进军OLAP领域!
  • msql的乐观锁和幂等性问题解决方案
  • Quartus 开发可实现人工智能加速的 FPGA 系统
  • rockerMQ实战 事务消息、延迟消息
  • 【Ruoyi-Vue】动态修改ruoyi-vue路由标签名称
  • MYSQL丢失pid处理方式
  • ZAB 和 RAFT分别是什么?它们的区别是什么?
  • STM32之FreeRTOS移植(重点)
  • 一次消谐器更换操作流程及注意事项
  • 7系fpga带microblaze做固件及固化
  • leetcode501.二叉搜索树中的众数:迭代中序遍历的众数追踪与数组动态更新
  • 重磅发布 | 复旦533页《大规模语言模型:从理论到实践(第2版)》(免费下载)
  • spring Data JPA详细介绍。
  • 3.20 工程计价数字化与智能化