彭文元
云和恩墨技术专家
服务于某省移动公司BES中间件和数据库运维,在IT行业拥有10年以上的工作经历,包含产品开发、需求调研、数据库以及中间件的实施维护等。擅长 BES 中间件和 ORACLE 数据库运维管理、c/c++、集成部署、shell/perl 脚本开发。长期服务于电信、移动通讯行业。具有丰富的数据库和中间件运维管理经验,推崇用程序来代替大量重复繁琐的工作,努力提高工作效率。
本文整理自上周四晚云和恩墨大讲堂分享的关于主题:中间件BES连接池的配置和问题诊断方法。
概述
中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源。中间件位于客户机/服务器的操作系统之上,管理计算机资源和网络通讯。是连接两个独立应用程序或独立系统的软件。
中间件产品种类较多,按产品分类有应用服务器中间件、消息中间件、交易中间件等。本次讲述的是有关应用服务器中间件。应用服务器中间件产品目前市面上有宝兰德的 BES、Oracle WebLogic、IBM WebSphere 等等。
中间件应用服务器连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及最大空闲时间等等。也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。下面就宝兰德的BES中间件来讲解 JDBC 连接池的配置和问题诊断的一些方法,不同中间件连接池配置以及问题诊断方法有许多共性,可以供大家参考。
BES 中间件支持常用的 ORACLE、DB2、Informix、Derby、SQL Server、MySQL 等多种数据库的连接配置。
1JDBC 连接池配置参数说明
下面是 BES 连接池的配置页面:
1. 常规配置
以下是常规配置参数列表说明:
2. 连接配置
以下是连接配置参数列表说明:
3. 池参数
以下是池参数配置参数列表说明:
4. 连接验证
以下是连接验证列表参数说明:
5. 事务
以下是事务列表参数说明:
备注: 以上参数除了必填选项外,没有特殊要求修改的话,其他参数都是默认值。
2JDBC 连接池简要配置
以下只列了简要的步骤,这里不做详述,详细的配置步骤可以参见官方文档。
1. 查看 JDBC 连接池列表
在管理控制台查看 JDBC 连接池列表:
1) 域范围 JDBC 连接池列表:首页点击 JDBC 的“连接池”链接或在管理控制台左侧导航区点击“管理和部署”-->“资源管理”-->“JDBC”-->“连接池”节点,右侧显示 JDBC 连接池列表。
2) 查看连接池详细信息:点击JDBC连接池“JNDI 名称”链接。
注意: 系统提供三个连接池:DerbyPool、__reqTracePool和__TimerPool。
2. 新建 JDBC 连接池
在管理控制台新建 JDBC 连接池:
1) 在首页点击“JDBC”的“连接池”链接或在管理控制台左侧导航区点击“管理和部署”-->“资源管理”-->“JDBC”-->“连接池”节点。
2) 右侧显示 JDBC 连接池列表,点击“新建”按钮,进入新建连接池页面,填写可配置项
3连接池合理配置的建议
连接池的配置是否合理主要与池配置参数有很大关系,下面我们着重探讨池配置参数。
对于连接池配置参数,每个参数配置多少?与数据库以及应用有什么关联关系?带着这些问题,我们一起来思考分析。
我们知道如下两点:
1. 连接池中的每个数据库连接,都要在数据库中创建一个对应连接
2. 连接池总的连接数为每个实例应用使用连接池的连接数之和
通过以上两点,我们可以做以下几点推算:
a)连接池的使用连接总数<=数据库能承载的最大连接数
b)连接池的使用连接总数>=应用实际需求的最大连接数
c)考虑数据库有多个应用项目在使用,平衡各应用可以允许的连接数。
3. 连接池最重要的几个参数
a) 最小连接数
此参数是初始创建的最小连接数,对于初始连接要求比较大的应用来说,合理的调大此参数到匹配值,减少分配回收类的申缩对资源的消耗,有利于应用获取快速的连接,提高响应速度。
b) 最大连接数
此参数是连接池允许创建的最大连接数,当应用的真实环境需求连接数实际不够用的时候,可调大此参数到可满足最大连接的需求值。
c) 连接数调整大小
此参数是当连接池中不存在可用连接时,每次创建的新的连接个数。
对于应用实际需求过程中,单位时间内需求连接相对较高,可适当调大这个参数,可以每次快速创建多个连接,满足当前连接的新请求。
d) 空闲超时时间
此参数是连接在连接池空闲保留时间,若某个连接空闲时间超过此值,则此连接会被删除。
对于应用实时性高,短连接的情况较多的情况,可以调低此值,提高回收连接的频率来满足其他应用需求。
最后,我们可以通过以上几点经验,结合应用实际情况,做好规划并测试好连接池参数合理的配置。
4问题诊断方法
连接池出现问题的第一步是通过查看连接池相关的报错日志或界面监控信息,大致了解问题的症状和确定问题的方向。
如果发现应用对连接池的配置如IP、端口、数据库名称、用户名、口令等配置都正常时,却无法分配连接,连接不了数据库。首先我们想到是网络,当排除网络问题后,我们就应该看 JDBC 驱动了,JDBC 驱动包没有放在正常的位置,或者 JDBC 驱动包没有加载,或者 JDBC 驱动程序版本过低等几个方面去分析处理。如果驱动没有问题,那么就可以分析应用代码,看下是使用哪种架构,比如 spring+hebirnate、dbcp、JNDI 等等,看看配置是否正常,编码是否有问题等。
以下是我在诊断问题时的一些具体方法,和大家分享,共同探讨。
1. 网络方面的问题
连接池网络方面的问题,在很多平台可以通过 ping 或 telnet 等命令验证网络是否连通以及端口是否开放,来确定具体的情况。
若是无法正常 ping 通数据库主机或者能 ping 通的情况下用 telnet 验证对端数据库监听的端口未开放,则需要寻求主机或网络工程师的帮助进一步诊断。
2. 数据库 sqlnet.ora 白名单限制
通过查看应用主机IP是否在数据库 sqlnet.ora 白名单中。
问题案例:某移动公司应用厂家工程师反映宽带客服中间件 BES 连接池无法连接数据库。
原因分析:
首先查看中间件日志报错信息如下:
从日志来看,连接池分配不成功。向应用人员了解下具体情况,以前连接正常,一直以来未修改过配置。接下来检查应用主机到数据库主机之间的网络情况是正常的,那么猜测有可能与数据库白名单有关系,因为最近局方因为安全问题,重新整理过数据库的白名单。于是检查了数据库白名单情况,发现应用主机的IP的确没有添加到数据库白名单文件sqlnet.ora中。
处理方法:数据库工程师将应用服务器IP添加到 sqlnet.ora,把监听 reload 后,中间件连接池一切恢复正常。
3. 负载均衡
负载均衡器按类型分为硬件级和软件级。目前很多电信运营商都采用硬件级的负载均衡器。下面是一个使用F5硬件级的负载均衡设备的案例,中间件用的是 WEBLOGIC。
问题案例:某电信运营商中间件 WEBLOGIC10G,反映连接池 OVERLOAD,应用端无法连接数据库,业务无法运行。
原因分析:
通过具体了解,中间件创建了4个集群,每个集群包括3个实例,部署的应用完全一样。
查看其中一个集群实例的连接池负载情况如下(其他集群实例情况基本相同)
上图中实例iomserverA1和实例iomserverA2的活动连接数都为1,而实例iomserverA3为20,连接状态为overloaded,表明连接池资源耗尽。从中行列的数据可以分析出,负载到集群实例的连接并不均衡,实例iomserverA3的连接池资源耗尽。
联系F5厂家工程师查看F5负载的情况,同样发现负载到应用端的连接不均衡,由此说明F5负载不均,导致部分应用实例连接池没能完全利用,从而使得某个实例连接池资源耗尽,其他实例还有很多空闲。
处理方法:
F5调整算法配置之后,负载情况正常,不在报错 overloaded。另外,和应用厂家沟通,由于业务的发展,为了能承载更大的连接业务,我们根据各方面综合考虑,调大了 Maximum Capacity 到60(以前是20),如下图所示:
4. 参数配置不合理
问题案例:某电信运营商应用系统连接池 overload,数据库也无法连接上。
原因分析:通过具体了解,应用系统创建了12个集群,集群下有8个实例,平均部署在四台主机。连接的是 oracle11g 数据库。
a) 因为此系统以前连接池使用一直正常,通过应用工程师检查应用端导致连接池耗尽的风暴连接,发现是因为一个应用程序通过大量多线程频繁的打开和关闭连接,从而导致连接池很快被耗尽。
b) 查看连接池的主要参数配置情况如下:
最小连接数=30
最大连接数=120
通过计算连接数据库的总的理论最大连接=最大连接数*集群数*实例数=120*12*8=11520
通过数据库工程师查看 oracle 的 process 参数为8000。
由此我们不难看出,当应用在峰值的情况下发起连接,造成中间件连接池过高,甚至超过了对数据库的连接配置,导致数据库无法接受其他连接,停止响应。
处理方法:
a) 和应用厂家沟通,调整应用程序对数据库连接的模式,调小应用并发连接线程数。
b) 调小连接池参数最大连接数为80,总的理论最大连接=80*8*12=7680,小于 oracle 数据库的 process 参数8000,避免超过数据库连接控制。
问题案例:某电信运营商微信厅推促销活,使用同一个时间点 CRM 数据库连接过多,致使 CRM 系统本身出现业务上的断开,白屏故障。
原因分析:
首先查看 CRM 数据库,发现电渠微信应用到 CRM 数据库的连接池达到3800左右,而 CRM 库本身允许的连接数为4500,CRM 系统自身就要用到此库。
其次在 BES 中间件上查看微信应用连接池配置,发现微信应用有24个服务实例,连接池的配置最大连接数为300,也就是说最大时可以允许24*300=7200个连接,大于数据库允许最大连接数4500。
处理方法:
a) 原本的应用连接池配置不恰当,没有考虑数据库的实际情况,数据库有多个应用用户在使用,允许的最大连接为4500,故调小连接池参数最大连接数为80,这样确保微信厅最大时发可起80*24=1920个连接。
b) 由于微信厅应用实时性高,调整连接池配置的空闲超时时间从300秒调小为60秒。使其连接用完后还给连接池只保留60秒。
5. 连接池泄漏
连接池泄漏指的是如果在某次使用或者某段程序中没有正确地关闭 Connection、Statement 和 ResultSet 资源,那么每次执行都会留下一些没有关闭的连接,这些连接失去了引用而不能得到重新使用,因此就造成了数据库连接的泄漏。数据库连接的资源是宝贵而且是有限的,如果在某段使用频率很高的代码中出现这种泄漏,那么数据库连接资源将很快被耗尽,影响系统的正常运转。
出现了连接池泄漏一般采用如下方法进行分析:
a) 从中间件应用服务器的控制页面,打开监控日志进行分析。
b) 从应用代码层面找到具体有问题的代码片断,修正应用代码。
在应用代码层面,建议采用 try finally 的异常捕捉机制,将关闭数据库连接放在 finally 代码块中,这样一旦有异常发生,也可以正常关闭数据库连接。
建议开发商检查代码,编写 finnally 语句块进行处理。
例如:伪代码如下:
问题案例:某电信运营商应用系统数据库连接无法分配,提示达到其配置最大值,但数据库侧看此主机连接过去的 session 未达到最大值。
原因分析:
查看 BES 中间件上应用连接池配置,最大连接数为80,而此主机上运行了4个服务,那就共有4*80=320个连接;登录应用主机 netstat –an|grep 数据库IP |grep 1521|wc –l 发现连接数确实已经有320个,通过查看数据库 session,发现从此 machine 连接过来的连接状态 ACTIVE 有187个、状态 INACTIVE 有23个,共210连接。这说明数据库连接数小于应用主机上创建的连接数。
难道是回收时间还没到,看了一下空闲超时时间是300秒,于是我们再等超过300秒以上时间后,看到发现还是没有回收,这时我们推测应该是泄漏了。
处理方法:
给每个 BES 应用实例添加如下两个系统属性用于泄漏回收
com.BES.resource.leakDetect=true和com.BES.ejb.resource.leakDetect=true
6. Jvm内存不足
由于 jvm 配置太小,在日志中查看报错如下类似信息 java.lang.OutOfMemoryError: Java heap space,
对于这种情况,也会导致连接池资源无法正常分配,从而连接失败,一般解决办法是增大 jvm 到一个合理的值,避免导致 Out Of Memory Error。
7. Jdbc thin 和 oci 驱动
thin 是一种瘦客户 orache 端的连接方式,即采用这种连接方式不需要安装 oracle 客户端,只要求 classpath 中包含 jdbc 驱动的jar包就行。thin 就是纯粹用 Java 写的 ORACLE 数据库访问接口。
oci 是一种胖客户端的连接方式,即采用这种连接方式需要安装 oracle 客户端。oci 是 Oracle Call Interface 的首字母缩写,是 ORACLE 公司提供了访问接口,就是使用 Java 来调用本机的 Oracle 客户端,然后再访问数据库,优点是速度快,但是需要安装和配置数据库。
从相关资料可以总结出以下几点:
1. 从使用上来说,oci 必须在客户机上安装 oracle 客户端或才能连接,而 thin 就不需要,因此从使用上来讲thin 还是更加方便,这也是 thin 比较常见的原因。
2. 原理上来看,thin 是纯 java 实现 tcp/ip 的 c/s 通讯;而 oci 方式,客户端通过 native java method 调用 c library 访问服务端,而这个 c library 就是 oci(oracle called interface),因此这个 oci 总是需要随着 oracle 客户端安装。
目前 Jdbc thin 不支持 Oracle 的 TAF 功能,jdbc oci 支持 TAF。
因此,应用要实现 oraclerac 的 TAF 功能,应采用 jdbc oci 驱动。