1. 连接池相关技术调研
1.1. 池化技术
1.1.1. 池化技术概述
池化是一种通过复用来提升软件系统性能的的软件技术。
其原理是,通过复用对象来减少创建对象、垃圾回收的开销,这样能够减少资源对象的创建次数,提高程序的性能,特别是在高并发下这种提高更加明显。
使用池化技术缓存的资源对象有如下共同特点:
- 对象创建时间长
- 对象创建需要大量资源
- 对象创建后可被重复使用
池化技术应用:
- 线程池
- JDK中ThreadPoolExecutor
- Tomcat中的线程池
- 内存池
- 连接池
- HttpClient连接池
- JDBC连接池 (C3P0、BoneCP、DBCP等)
- Redis 连接池 (jedis)
- 等等
1.1.2. commons-pool2 包
commons-pool2是一个广泛使用的对象池组件,由apache基金会开源,当前最新版本是Version 2.8.0
核心类:
- PooledObjectFactory:工厂类,负责具体对象的创建、初始化,对象状态的销毁和验证
- ObjectPool:实现对对象存取和状态管理的池实现;如:线程池、数据库连接池
- PooledObject:池化对象,是需要放到ObjectPool对象的一个包装类。添加了一些附加的信息,比如说状态信息,创建时间,激活时间,关闭时间等
ObjectPool的核心数据结构:* private final Map<T, PooledObject<T>> allObjects 存储所有的对象(不含销毁的对象)* private final LinkedBlockingDeque<PooledObject<T>> idleObjects 后者用于存储空闲的对象,供borrow
// commons-pool2的使用demopublic static void main(String[] args) {// 创建池对象工厂PooledObjectFactory<Resource> factory = new MyPoolableObjectFactory();GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();// 最大空闲数poolConfig.setMaxIdle(5);// 最小空闲数poolConfig.setMinIdle(1);// 最大池对象总数poolConfig.setMaxTotal(20);// 逐出连接的最小空闲时间 默认1800000毫秒(30分钟)poolConfig.setMinEvictableIdleTimeMillis(1800000);// 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1poolConfig.setTimeBetweenEvictionRunsMillis(1800000 * 2L);// 在获取对象的时候检查有效性, 默认falsepoolConfig.setTestOnBorrow(true);// 在归还对象的时候检查有效性, 默认falsepoolConfig.setTestOnReturn(false);// 在空闲时检查有效性, 默认falsepoolConfig.setTestWhileIdle(false);// 最大等待时间, 默认的值为-1,表示无限等待。poolConfig.setMaxWaitMillis(5000);// 是否启用后进先出, 默认truepoolConfig.setLifo(true);// 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认truepoolConfig.setBlockWhenExhausted(true);// 每次逐出检查时 逐出的最大数目 默认3poolConfig.setNumTestsPerEvictionRun(3);// 创建对象池final GenericObjectPool<Resource> pool = new GenericObjectPool<Resource>(factory, poolConfig);for (int i = 0; i < 21; i++) {new Thread(new Runnable() {@Overridepublic void run() {try {// 注意,如果对象池没有空余的对象,那么这里会block,可以设置block的超时时间Resource resource = pool.borrowObject();System.out.println(resource);Thread.sleep(3000);pool.returnObject(resource);} catch (Exception e) {e.printStackTrace();}}}).start();}}
1.1.3. Alibaba-Druid
阿里巴巴数据库事业部出品,为监控而生的数据库连接池。号称是Java语言中最好的数据库连接池,能够提供强大的监控和扩展功能。
Druid首先是一个数据库连接池。Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验。
同时Druid不仅仅是一个数据库连接池,它包括三个部分:
- 基于Filter-Chain模式的插件体系。
- DruidDataSource 高效可管理的数据库连接池。
- SQLParser
Druid的功能:
- 替换DBCP和C3P0。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池。
- 可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助。
- 数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback。
- SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况。
- 扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件。
