首页 > 数据库 >稳,从数据库连接池 testOnBorrow 看架构设计 | 京东云技术团队

稳,从数据库连接池 testOnBorrow 看架构设计 | 京东云技术团队

时间:2023-06-21 12:06:10浏览次数:52  
标签:架构设计 testOnBorrow 数据库 commons 校验 连接池 return 连接 pool

本文从 Commons DBCP testOnBorrow 的作用机制着手,管中窥豹,从一点去分析数据库连接池获取的过程以及架构分层设计。

以下内容会按照每层的作用,贯穿分析整个调用流程。

1️⃣框架层 commons-pool

The indication of whether objects will be validated before being borrowed from the pool.

If the object fails to validate, it will be dropped from the pool, and we will attempt to borrow another.

testOnBorrow 不是 dbcp 定义的,是commons-pool 定义的。commons-pool 详细的定义了资源池使用的一套规范和运行流程。

/**
 * Borrow an object from the pool. get object from 资源池
 * @see org.apache.commons.pool2.impl.GenericObjectPool#borrowObject(long)
 */
public T borrowObject(final long borrowMaxWaitMillis) throws Exception {
	
	PooledObject<T> p = null;
	
    // if validation fails, the instance is destroyed and the next available instance is examined. 
    // This continues until either a valid instance is returned or there are no more idle instances available.
	while (p == null) {
        // If there is one or more idle instance available in the pool, 
        // then an idle instance will be selected based on the value of getLifo(), activated and returned.
		p = idleObjects.pollFirst();
		if (p != null) {
            // 设置 testOnBorrow 就会进行可用性校验
			if (p != null && (getTestOnBorrow() || create && getTestOnCreate())) {
				boolean validate = false;
				Throwable validationThrowable = null;
				try {
                    // 具体的校验实现由实现类完成。
                    // see org.apache.commons.dbcp2.PoolableConnectionFactory
					validate = factory.validateObject(p);
				} catch (final Throwable t) {
					PoolUtils.checkRethrow(t);
					validationThrowable = t;
				}
				if (!validate) {
					try {
                        // 如果校验异常,会销毁该资源。
                        // obj is not valid and should be dropped from the pool
						destroy(p);
						destroyedByBorrowValidationCount.incrementAndGet();
					} catch (final Exception e) {
						// Ignore - validation failure is more important
					}
					p = null;
				}
			}
		}
	}

	return p.getObject();
}

2️⃣应用层 commons-dbcp

dbcp 是特定于管理数据库连接的资源池。

PoolableConnectionFactory is a PooledObjectFactory

PoolableConnection is a PooledObject

/**
 * @see PoolableConnectionFactory#validateObject(PooledObject)
 */
@Override
public boolean validateObject(final PooledObject<PoolableConnection> p) {
	try {
		/**
		 * 检测资源池对象的创建时间,是否超过生存时间
		 * 如果超过 maxConnLifetimeMillis, 不再委托数据库连接进行校验,直接废弃改资源
		 * @see PoolableConnectionFactory#setMaxConnLifetimeMillis(long)
		 */
		validateLifetime(p);
		// 委托数据库连接进行自我校验
		validateConnection(p.getObject());
		return true;
	} catch (final Exception e) {
		return false;
	}
}

/**
 * 数据库连接层的校验。具体到是否已关闭、是否与 server 连接可用
 * @see Connection#isValid(int)
 */
public void validateConnection(final PoolableConnection conn) throws SQLException {
	if(conn.isClosed()) {
		throw new SQLException("validateConnection: connection closed");
	}
	conn.validate(_validationQuery, _validationQueryTimeout);
}

3️⃣基础层 mysql-connector-java

Returns true if the connection has not been closed and is still valid.

这个是 java.sql.Connection 定义的规范。具体实现根据对应数据库的driver 来完成。使用某种机制用来探测连接是否可用。

/**
 * 调用 com.mysql.jdbc.MysqlIO, 发送ping 请求,检测是否可用
 * 对比 H2 数据库,是通过获取当前事务级别来检测连接是否可以。但是忽略了 timeout 配置,毕竟是 demo 数据库 

标签:架构设计,testOnBorrow,数据库,commons,校验,连接池,return,连接,pool
From: https://blog.51cto.com/u_15714439/6528037

相关文章

  • 数据库可以影响整体软件的架构设计,-- 那是当然!
    数据库DBA在整体软件的成型的过程中大部分的单位都将这个职位定位成一个运维的职位。 当然既定的现实存在即合理,这也是无法辩驳的,但实际上DBA到底应该不应该就是也给运维的职位,都2021年了,咱们的开始论论了。我们先罗列一下大部分人认为的DBA应该做什么1  安装数据库,安装数......
  • Java_Jdbc_连接池的testQuery/validationQuery设置
     JDBC连接池的testQuery/validationQuery设置 在《Tomcat中使用Connector/J连接MySQL的超时问题》帖子中想要增加对连接池中连接的测试/验证,防止数据库认为连接已死而Web应用服务器认为连接还有效的问题,Mysql文档中提到Tomcat文档中的例子中用的是validationQuery,但是网......
  • 系统架构设计师笔记第18期:NoSQL数据库
    NoSQL数据库通常指非关系型数据库,是一种基于数据键值对存储、高度分布式、支持动态查询的数据管理系统。NoSQL数据库的设计目的是为了解决传统关系型数据库无法处理的大型应用程序的数据存储和管理问题。它们通常具有以下特点:灵活性:NoSQL数据库没有固定的表结构和查询语言,允许在......
  • OSI七层协议剩余、socket模块、半连接池
    传输层之TCP与UDP协议TCP与UDP都是用来规定通信方式的 通信的时候可以随心所欲的聊也可以遵循一些协议符合要求的聊随心所欲的聊:文字图片视频遵循一些协议:开头带尊称首行空两个只准用官话ps:不遵循上述协议也可以通信只不过遵循了更合规合法合理!!!1.TCP协议(重......
  • 系统架构设计师笔记第17期: 关系数据库
    数据库的分类可以根据不同的标准进行划分:根据数据结构分类:1.1关系数据库(RelationalDatabase):关系数据库是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据,以表格形式存储数据,并支持事务处理、多用户访问、数据安全性和完整性控制等功能。1.2非关系型数据......
  • 任务调度系统架构设计:基于缓存的改进
    目录1.引言2.技术原理及概念2.2.技术原理介绍3.实现步骤与流程4.示例与应用5.优化与改进随着互联网和信息技术的不断发展,任务调度系统已经成为了企业和个人使用的重要工具。一个高效的任务调度系统可以提高生产效率,降低人工成本,优化工作流程,提高企业竞争力。然而,传统的任务......
  • 操作系统架构设计:如何优化系统性能和资源利用率
    目录1.引言2.技术原理及概念2.1.基本概念解释2.2.技术原理介绍3.实现步骤与流程3.1.准备工作:环境配置与依赖安装3.2.核心模块实现3.3.集成与测试操作系统架构设计:如何优化系统性能和资源利用率随着计算机硬件性能的不断提高和软件功能的不断扩展,操作系统在系统性能、资......
  • 系统架构设计师笔记第16期:数据库基本概念
    数据库技术的发展数据库技术在过去几十年中经历了显著的发展和演变。层次数据库和网状数据库:20世纪60年代和70年代初,层次数据库和网状数据库是主流的数据库模型。层次数据库使用树状结构组织数据,而网状数据库使用复杂的网络结构。这些数据库模型适用于特定的数据组织和查询需求,但缺......
  • 操作系统架构设计:如何优化系统性能和资源利用率
    目录1.引言2.技术原理及概念2.1.基本概念解释2.2.技术原理介绍3.实现步骤与流程3.1.准备工作:环境配置与依赖安装3.2.核心模块实现3.3.集成与测试操作系统架构设计:如何优化系统性能和资源利用率随着计算机硬件性能的不断提高和软件功能的不断扩展,操作系统在系统性能、资......
  • 数据库连接池-Druid的使用
       packagedruid;/**druid数据连接池**/importcom.alibaba.druid.pool.DruidDataSourceFactory;importjavax.sql.DataSource;importjava.io.FileInputStream;importjava.io.FileReader;importjava.sql.Connection;importjava.util.Properties;p......