项目情况:是一个大型公司的内部办公系统,该系统有两个和一般企业应用不太一样的特点:一是用户量非常多,人员数达到2W左右,另一个是采用分级管理的形式,各个分公司数据分开管理。
我们的定位:我们是作为业务平台的提供商参与这个项目的,我们提供底层的开发平台,系统集成商在此基础上进行二次开发。
在项目从开发到部署的过程中遇到了很多的问题,也反映出很多问题。
一、怎么回事,跑得比猫还慢
项目开发完毕后部署在Ibm aix 小型机上,32G内存,16个cpu。应用服务器采用的是weblogic9.2,数据库是oracle10.0.2。上线后发现系统运行的非常缓慢,甚至比开发环境下的tomcat还要慢。于是开始排查原因,最开始是对SQL进行监控,优先考虑是数据库访问性能产生瓶颈。通过监控,发现很多业务需要执行大量的SQL语句,查看客户编写的相关代码,发现在查询数据时循环执行了大量SQL。主要原因在于他们在代码中循环调用了我们相关API,一个最典型的例子是通过用户ID查找用户NAME,他们在业务表格里没有保存用户name,而是在查询的时候通过用户ID查找用户name填充到页面,几乎每一个查询都是n+1。
另外由于平台使用了hibernate,使得oo编程得非常爽快,导致开发人员完全忽略了相应的数据库操作所带来的压力。很多业务逻辑直接通过PO叠加完成,把一些可以通过很少SQL完成的逻辑全部分散放置到PO里,导致了大量PO的交互和SQL语句。
开始优化SQL,优化的同时增加大量业务缓存。但优化完毕后运行缓慢的现象依旧存在,性能有了一定的提升但是不是非常明显。继续优化,其中考虑过多频繁访问的数据使用内存数据库的方式。但是优化过后在tomcat上效果明显,部署到生产环境就问题依旧。于是考虑weblogic的配置问题,作为开发平台提供商,我们只是提供系统开发相关方面的支持,对于应用服务器和数据库服务器只是做基本的配置系统可运行即可。但是在这个问题上系统集成商咬定是我们平台的问题不放,并且存在一个很严重的问题:他们使用的是盗版的weblogic,这样根本就没有相应的技术支持。
问题的解决:最后是找了一个BEA曾经的开发人员,问题实际非常的简单,现场部署的weblogic默认是运行在32位机器上,与64位机器存在一定的不兼容。通过替换相应的jar包,问题得到了解决,主要是IO方面。替换完毕后,速度提升了进30% 。该开发人员说,如果没有lisence,根本就不会得到这些替换的jar包。
二、内存耗尽了
访问速度的问题解决了,系统的使用量很快上来,马上遇到新的问题:内存耗尽了。严重到几乎每天都要out of memory一次。这种问题在客户现场频繁出现。
本地测试,tomcat,sun jdk 通过Jprofiler监测内存使用情况。在并发访问门户的情况下,内存确实存在暴涨的情况,100并发,内存使用立刻上升了150m左右,继续并发 100,再增长150m。但是很快在抵达高峰时会有一次gc发生,内存使用稳定在200m,内存里大量char[]数组对象。疲劳测试,内存使用曲线并没有出现逐渐上升泄露的情况。换weblogic和jrocket测试,gc发生的更加频繁,内存使用稳定。