最近项目上线,但是大下午的客服反应项目登录页面很慢,SA发现后立马重启后项目访问速度恢复。 排查问题时,发现nginx的页面访问速度都是在十秒左右,有部分二十秒,这个时间很奇怪。日志显示,项目并没有什么特殊的错误异常。跟据经验立马确认了下连接池的maxwait时间为10000,与是百分之九十肯定是项目中有连接池未关闭的操作。
但是此项目上线已经几天,说明此未关闭的地方很隐蔽,另外项目比较大,大家一起查了下DAO的代码,也没有什么头绪,因为正常所有的DAO操作在finally都有相关close操作,对于一些需要保持连接的操作,通过keepalive,也进行了急时关闭,所以要具体问题在哪很麻烦。
另外重启后,通过show processlist,发现此应用的连接数每天都会有一些增加,虽然不是很明显,但是每天有些增加,更坚定了我的判断。
由于项目是在原来老有项目中基础上开发,连接池使用了原有的tomcat自带的dbcp,其配制是通过JNDI配制。记得连接池是有自动释放连接的配制,通过google,找到资料如下:
设置数据源的removeAbandoned="true",removeAbandonedTimeout="60",logAbandoned="true"几个属性就可以了。 DBCP会自动把超过timeout时间仍未关闭的连接强制关闭,并且打出异常信息(包含打开连接的代码位置) ,其中第一参数,打开自动释放未被使用的连接,而第二参数为多长时间未被使用的连接,第三个参数打印dbcp自动关闭时,输出的log4j日志。(这些参数有些地方需要说明:1.removeAbandonedTimeout一定需要估量自己项目中某个操作最长使用的时间,其中此参数为秒。2.对于数据库连接池还是我们自己控制关闭更好些,而使用上面配制是为了帮忙找出未关闭的地方在什么地方。修正后,可以关闭这些配制。3.log4j的日志配制级别一定需要在debug以上日志才能输出)
修改以上配制后,服务器做了一次更新。前四天很正常,都没有错误的日志。在我以为自己判断失误的情况下,今天早上来一到公司,习惯性的扫描起日志来,突然发现了一堆
org.apache.tomcat.dbcp.dbcp.AbandonedTrace$AbandonedObjectException: DBCP object created 2011-07-29 08:30:25 by the following code was never closed: 让我异常兴奋。然后定位到详细的日志,定位到了代码。
查看代码后,这个BUG让我们很无语。一个同事把一些本是service判断属性是否为null的逻辑代码,放到了DAO里面,而此判断又是在DAO里面的try{}finally的外面,而DB的构造是在此DAO的外层,所以构造DB实例时,当出现此属性为NULL的情况时,会直接返回。这样跟据没有执行try{}finally里面的代码,即不存在close了。而此操作又是一个小权限的用户下,且此权限下某个特定逻辑时才会触发。这也是为什么几天都没有触发的原因。
到此,问题得到解决,把逻辑代码提出到外层service后,问题就得到解决了。通过此次问题的解决,让我考虑的东西又多了些。代码的review,service与dao的严格区分,DAO连接关闭的处理等等
问题解决了很开心,下面附一下默认DBCP连接池的配制参数的说明:
maxActive :连接池中可同时连接的最大的连接数(默认值为8,调整为20,高峰单机器在20并发左右,自己根据应用场景定)
maxIdle:连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限制(默认为8个,maxIdle不能设置太小,因为假如在高负载的情况下,连接的打开时间比关闭的时间快,会引起连接池中idle的个数 上升超过maxIdle,而造成频繁的连接销毁和创建,类似于jvm参数中的Xmx设置)
minIdle:连接池中最小的空闲的连接数,低于这个数量会被创建新的连接(默认为0,调整为5,该参数越接近maxIdle,性能越好,因为连接的创建和销毁,都是需要消耗资源的;但是不能太大,因为在机器很空闲的时候,也会创建低于 minidle个数的连接,类似于jvm参数中的Xmn设置)
maxWait :最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待(默认为无限,调整为60000ms,避免因线程池不够用,而导致请求被无限制挂起)
poolPreparedStatements:开启池的prepared(默认是false,未调整,经过测试,开启后的性能没有关闭的好。)
maxOpenPreparedStatements:开启池的prepared 后的同时最大连接数(默认无限制,同上,未配置)
minEvictableIdleTimeMillis :连接池中连接,在时间段内一直空闲, 被逐出连接池的时(默认为30分钟,可以适当做调整,需要和后端服务端的策略配置相关)
removeAbandonedTimeout :超过时间限制,回收没有用(废弃)的连接(默认为 300秒,调整为180)
removeAbandoned :超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收(默认为false,调整为true)
相关推荐
在深入探讨数据库连接池中连接关闭的问题之前,我们首先需要了解数据库连接池的基本概念以及它在现代应用程序中的重要性。数据库连接池是一种管理多个数据库连接的方法,旨在提高应用程序性能并减少资源消耗。通过...
描述中提到的“解决连接池不够的问题,多连接的问题”,意味着在实际项目开发中,可能会遇到因为数据库连接数量不足或者频繁创建和关闭连接导致的性能瓶颈。通过使用连接池,开发者可以在应用启动时预先分配一定数量...
- **连接回收**:使用完毕后,应用程序不应直接关闭连接,而是将其返回到连接池,供其他请求复用。 - **超时管理**:连接池需要监控每个连接的空闲时间,避免因长时间未使用的“僵尸”连接占用资源。 - **线程...
为了解决这个问题,JDBC引入了连接池的概念,通过代理模式实现了对数据库连接的智能管理。 代理模式是一种设计模式,它允许我们为一个对象创建一个代理,以控制对这个对象的访问。在数据库连接池的上下文中,代理类...
为了解决这个问题,开发人员通常会使用连接池来管理和复用已建立的Socket连接。 首先,我们来看一下Socket的基本概念。Socket是网络编程中的一个抽象概念,它代表了两台机器间的一个双向通信链路。在Java中,`java...
此外,连接池还需要维护功能,包括定期检查并关闭长时间未使用的连接,以避免资源浪费和潜在的数据库锁定问题。还可以设置最大空闲时间和最大连接存活时间等策略。 使用数据库连接池的益处主要包括: 1. 提高性能:...
为了解决这个问题,引入了Socket连接池的概念。 连接池的工作机制如下: 1. 初始化:在服务器启动时,预先创建一定数量的Socket连接,放入池中。 2. 借用与归还:当客户端请求到来时,服务器从连接池中取出一个已...
在IT行业中,数据库连接管理是应用系统性能优化的关键一环,而JDBC连接池就是解决这一问题的有效工具。本文将深入探讨如何自定义JDBC连接池,并对常用的连接池技术进行介绍。 首先,自定义JDBC连接池的核心在于管理...
6. **超时和健康检查**:连接池会定期进行健康检查,检测连接是否还活跃,如果发现连接已断开,会自动尝试重新建立连接。 在源码分析中,我们可以关注以下几个关键点: - 连接工厂类的创建方法,了解如何配置...
数据库连接池(connection pool)的工作原理是为了解决资源的频繁分配、释放所造成的问题。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时...
本话题将深入探讨如何在C++环境中利用连接池技术实现对Oracle数据库的高速连接与访问。 一、Oracle数据库基础 Oracle数据库提供了一套完整的数据管理解决方案,包括事务处理、数据仓库、网络数据库、安全性等。它的...
数据库连接池是一种资源管理技术,它预先创建并维护一定数量的数据库连接,当应用需要时,可以从池中获取连接,使用完毕后归还而不是直接关闭,从而减少了频繁创建和销毁连接的开销。在.NET Core中,对于MySQL数据库...
然而,了解连接池的内部工作原理对于优化数据库操作和解决相关问题至关重要。 个人实现Java连接池源码可以让你深入理解这一过程。首先,我们需要定义一个连接池类,这个类通常包含以下组件: 1. **连接池初始化**...
在软件开发中,特别是涉及到与数据库交互的应用,连接池的使用能够显著提升系统效率。本文将详细解释数据库连接池的工作原理、优缺点以及如何进行管理和配置。 数据库连接池,如ADO.NET中的实现,是一种复用已存在...
连接超时则可能是因为长时间未使用的连接被数据库自动关闭,但连接池并不知情,此时需要设置合理的超时策略。 对于初学者来说,理解JSP和数据库连接池的工作原理及其在实际应用中的配置和使用方法至关重要。这份...
Java 连接池是一种优化数据库访问效率的机制,它解决了在Web应用程序中频繁建立和释放数据库连接所导致的性能问题。随着B/S架构的广泛应用,Java应用程序通过JDBC(Java Database Connectivity)与数据库进行交互。...
数据库连接池的出现解决了这个问题。它是一种预创建的数据库连接集合,应用程序在需要时可以从池中获取一个已存在的连接,而不是每次都新建。使用完毕后,连接会归还到池中,而不是立即关闭,以便后续请求可以复用。...