日期:2014-05-16  浏览次数:20447 次

一次webservice连接数据库超时问题排查经历

????? 一、服务器环境:suse操作系统,IBM WebSphere,oracle数据库。平台有一个短信发布系统。平台内外网隔离,数据通过网闸同步。该webService用来提供其他系统短信发送以及查询短信状态使用。

??????? 二、最初设计:其他系统调用接口-->插入短信管理表-->触发器生成短信发送表-->网闸同步到外网-->外网短信发送程序发送短信-->网闸将发送状态同步到内网短信发送表,再将短信发送管理表和短信发送表用视图关联将合适的数据返回给其他系统。

???? 补充:由于内外网隔离,采用第三方网闸软件,内网数据变动(增删改)时会同步到外网,外网有变动时也是同步到内网。

???? 三、历程

???? 开始测试时,当短信发送了20多条的时候开始出现没有收到短信,有的要大约30分钟才能收到。到数据库查看发现没有插入数据库。查看was日志发现有线程挂起,赶紧重启应用,was节点。后来多次观察发现有时候挂起的线程会释放,不过还是危险性太高,将整个平台弄瘫就不合算了。

???? 这块是自写了一个数据库连接池,代码如下:


private static DataSource setupDataSource() {

BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName(DBDRIVER);
bds.setUrl(DBURL);
bds.setUsername(DBUSER);
bds.setPassword(DBPWD);
bds.setInitialSize(10);
bds.setMaxActive(30);
return bds;
}
?????? 和同事讨论了一下,怀疑是吧数据库连接池用光了,但是还能用pl/sql连上数据库,那数据库连接应该是能用光。但是上面代码中红色部分总归是问题,每调用setupDataSource一次就就会产生一个新的连接池。因此将代码改为:

private?static?BasicDataSource?bds?=?new?BasicDataSource();

???????static{

??????????????bds.setDriverClassName(DBDRIVER);
??????????????bds.setUrl(DBURL);
??????????????bds.setUsername(DBUSER);
??????????????bds.setPassword(DBPWD);
??????????????bds.setInitialSize(10);
??????????????bds.setMaxActive(30);?
???????}
???????
???????public?static?DataSource?setupDataSource()?{
??????????????return?bds;
???????}
问题依然存在,又看保存方法中connection为静态类成员变量又怕没有及时关掉或者并发太多时会串掉 ,又将connection改为方法变量,预料中问题依然存在,后来又改为was数据库连接池,修改为was连接池的时候又遇到一些问题,就是jndi的名字,本来配置的时候就没有jdbc/开头或者jndi/开头,又自作聪明的加上了,结果又报错没有找到was数据库连接池 。但是问题依然存在。

????? 此时感觉到可能是数据库方面的问题。又仔细看了日志,报

java.net.SocketInputStream.socketRead0