项目做完后,因产品部着急上线给领导演示,所以仓促未经测试部门测试直接上线。因怕周五上线后,出现bug周六周日无法修改bug,所以项目上线时间安排在周四。 周四上线后,周五上午未出现任何情况,下午到怀柔后,小强说项目在报警,因我手机收不到报警短信,所以没有在意。在此期间,小强见到我就说,项目在报警。
针对项目在报警,回到公司后,我们着手寻找问题所在原因。以下是整个解决过程的一个全程记录。
1.2011-04-27,修改sqlmap-config.xml,将参数调大了一倍
看后台数据库连接池好象被耗尽,所以试着将sqlmap-config.xml相关参数调大一倍,原始参数为:
<settings cacheModelsEnabled="false" enhancementEnabled="false"
lazyLoadingEnabled="true" errorTracingEnabled="true"
useStatementNamespaces="true" maxRequests="32" maxSessions="10"
maxTransactions="5" />
修改成:
<settings cacheModelsEnabled="false" enhancementEnabled="false"
lazyLoadingEnabled="true" errorTracingEnabled="true"
useStatementNamespaces="true" maxRequests="64" maxSessions="20"
maxTransactions="10" />
修改完成后,运行一天后,又报警了,本次修改失败。
2.将spring配置文件中的参数singleton="false"全部删除
再次检查项目,发现spring配置文件中的service层的bean都有参数singleton="false"。当singleton设为false的时候,它会每次请求都生成一个对象,这对系统压力很大,所以这次将singleton="false"统统删除。
修改后,观察了一天,报警依旧。
3.将显示照片的输入流全部关闭
再次查看代码,发现在显示照片的时候,输入流全都没关闭。所以这次我们在显示照片的地方都加上了ins.close();。
修改完,部署运行一天后,报警依旧,再次修改失败。
4.将初始化方法名由initCard()重命名为insertCard
查看spring的配置文件,发现insert,update,delete此类方法都配置了事务,而插入操作initCard未配事务。加上后台日志显示注册成功后,老报空指针异常。感觉就是在执行这个sql时,事务一直未提交,导致连接池一直未释放。
将initCard()方法重命名为insertCard,部署运行一天后,报警依旧,再次修改失败。
5.去排序,将按姓名搜索时的sql语句由 like '%$name$%' 改为了 like '$name$%'
数据库连接池一直未释放,感觉有sql语句一直未执行完成。这次寻求DBA帮助,查看有没有长连接的sql语句。DBA查看后,发现有两个sql语句执行了有一个小时一直未完成。想看具体的sql语句,没想到这个表有140个字段,sql语句只保存了一小部分。没办法,我们只好将正式库上的几百万条数据导到了开发库上。为了模拟正式机,我们将开发库的数据库连接方式也改为了连接池方式。数据导完后,测试发现按姓名搜索很慢。DBA一看到like '%$name$%'就说,name字段虽然建了索引,但在前面加百分号,索引无效,所以执行速度很慢。这次将like '%$name$%' 改为了 like '$name$%'。但是搜”李明”时,查询结果返回的量有点大,速度还是有点慢。检查我们发现select方法和count方法都有order by。而这里的查询order by没有必要,所以也去了。
去完排序,网站运行速度大大加快,感觉问题解决了。没想到部署运行一天后,报警依旧,再次修改失败。
6.将未分页的查询语句换成了count语句
查看项目的服务器日志时,发现异常时打印”<weblogic.GCMonitor> <<anonymous>> <> <> <1304705xxxxxx> <BEA-310003> <Free memory in the server is 2,931,816 bytes. There is danger of OutOfMemoryError>”。看到这个,感觉是内存不足的问题。查看代码,发现按姓名搜索时有个查询语句没有分页,直接将所有的查询结果放入了内存,而执行这个查询语句的目的是获取结果集的大小。
获取结果集的大小,执行count语句即可,所以将这个方法换成了count方法。这次修改部署后,项目运行平稳,运行速度又提升了不少,到现在未收到报警短信,一切ok!
此次解决问题过程吸取经验教训如下:
1. 面对问题,要有针对性的去解决,不要无厘头的乱找;
2. 开发环境和测试环境尽量保持一致。开发环境数据量少,上线前要经过大数据量的测试;
3. 经验不足,特别是遇到内存泄露,不知道怎么去查看原因。