现在的位置: 首页 > 综合 > 正文

一次性能调优的实战

2013年11月05日 ⁄ 综合 ⁄ 共 4390字 ⁄ 字号 评论关闭

项目情况:是一个大型公司的内部办公系统,该系统有两个和一般企业应用不太一样的特点:一是用户量非常多,人员数达到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发生的更加频繁,内存使用稳定。
 
但是现场依旧频繁当机,内存根本释放不了,一直逐渐增长,典型的内存泄露。对系统缓存、单态对象包括spring管理的对象、IO流进行了统一
排查,依旧没有找到内存泄露的原因。使用IBM
工具分析heapdump文件,结果还是大量的char[]数组对象占据内存,查找应用,找不到相关业务对象引用。
 
问题解决:问题解决是一篇偶尔搜到的oracle论坛的帖子,这里http://forums.oracle.com/forums/message.jspa?messageID=1040570

。原因在于oracle10的数据库驱动对statement最后执行的结果集有着引用,并且不会释放,目的在于通过内存而换取更好的性能。数据
库连接采
用的是weblogic的连接池,关于connection有个相关的statement
cache设定,设定一个connection能够被缓存的statement个数,最大是1024,而现场就被设定为了1024!connection
pool的connection个数被设置为了500
。真是个恐怖的设置。在将1024改为10后,内存使用量轰然倒地,稳定在1g左右。这个设置是在前面系统访问速度存在问题时由系统集成商的开发人员设置
上去的,他们将所有和优化相关的参数全部开到了最大。这个问题要是用户购买的是正版的weblogic和oracle的话,相信也会很快得到解决。

三、线程阻塞

内存泄露的问题解决后,线程阻塞的问题浮出水面。系统集成商报告是线程死锁,通过分析工具其实是线程阻塞,主要问题在于系统用到了
synchronized关键字,对工作流相关API全部使用了synchronized,原因在这里:http:
//ronghao.javaeye.com/blog/205731

。分析发现一个工作项提交的操作在连接数据库时被挂起了20分钟!造成了大量线程的排队阻塞。被挂起的原因有很多种。我们采用的方法是将接口拆分和设置事
务timeout时间。但是这显然不是一个好方法。最后是去掉所有的synchronized关键字,将同步的问题交由数据库解决,问题解决。

四、反思

1、系统集成商为什么不购买正版?

2、开发平台提供商究竟在项目开发中处于一种什么样的位置?开发平台是否对所有软件开发问题都要负责?

3、开发平台是越封装越快乐吗?还是越封装越丑陋?

更具体的细节在这里:

 AIX+weblogic
性能诊断记录

http://www.blogjava.net/ronghao 荣浩原创,转载请注明出处:)

posted on 2008-09-01 13:49 ronghao
阅读(2734)
论(10)

 

 收藏
所属分类: 工作日


FeedBack:

#
 
re: 一次性能调优的实战
2008-09-01 14:26 | 隔叶黄莺
我也碰过这种性能问题,费尽周折才稳定下来

我们用的 WAS,连接池默认的被缓存的statement个数是10,但是用了 hibernate 的应用必须把这个值设置为0

其他就一些线程池,JVM 的参数调整,Tomcat 就简单,没多少要调优的,不过就是多用户并发的时候直接就会死掉。  

  更多评论

  

#
 
re: 一次性能调优的实战
2008-09-01 15:11 | 特斯通
这个问题主要是没有用正版引起的。jar包引起的问题最好在创建DOMAIN时不使用weblogic自带
的jdk的JAR。  

  更多评论

  
#
 
re: 一次性能调优的实战
2008-09-01 20:42 | Robin's Java
World

@隔叶黄莺

为什么Hibernate不能使用被缓存的statement了?能解释一下吗?  

  更多评论

  
#
 
re: 一次性能调优的实战
2008-09-01 22:36 | leekiang
一方面大家认为做业务系统没有技术含量,另一方面做的业务系统却奇烂无比,很多做出来的系统连企业的业务数
据的完整性都保证不了,更不用提别的了。
很多做业务的公司基本是能骗就骗,因为要把业务系统做好是需要投入的,还不如招些便宜的新人,做些表面上
好像能用的增删改查,把客户忽悠过去了事。
所以说做企业应用注定就是忽悠,但不排除有个别有钱的甲方自己养人开发这种情况。
  

  
多评论


  
#
 
re: 一次性能调优的实战[未登录]
2008-09-02 11:58 | letitbe
一个最典型的例子是通过用户ID查找用户NAME,他们在业务表格里没有保存用户name,而是在查询的时
候通过用户ID查找用户name填充到页面,几乎每一个查询都是n+1。
-----------------------------------

务表里存用户的name,我觉得这是一种不好的设计:一是本身就冗余了;二是如果用户的name改变了,那么多的业务表也要跟着改,太麻烦;另外用户同名
时容易让人产生误解,以为是同一个人。
这个问题可以用数据库分页+外连接解决啊  

  更多
评论


  
#
 
re: 一次性能调优的实战[未登录]
2008-09-02 12:16 | ronghao
@letitbe
yes.我要表达的意思是用户这样写代码造成了n+1的查询问题。解决问题的方法
可以是外连接,也可以是冗余字段。但是在平台封装提供API的情况下,用户选择了最简单的直接调用API,这种方式是我反对的。由此我也在想平台的封装问
题。所以对所有的业务操作我们都提供出直接的connection。  

  更多
评论


  
#
 
re: 一次性能调优的实战
2008-09-03 19:25 | bf1977
怎么能查看 部署的weblogic是运行在32位机器上,还是64位机器?  

  更多评


  
#
 
re: 一次性能调优的实战
2008-09-05 11:09 | zbl400
我就在想:
系统集成商为什么不购买正版,并且
那个大型公司,存在2w以上员工的大公司居然也会同意不购买正版,难道真的是一点也不顾忌法律吗?每个使用者出几元钱,就能买到正版了吧。
还想问
一下:
如果抓盗版的话,这个责任应该是在系统集成商上,还是在大型公司上呢?  

  更多评


  
#
 
re: 一次性能调优的实战
2009-02-12 16:52 | 赵斌
很好的经历啊,呵呵,部署生产环境、内存溢出、线程阻塞,几乎每个大型应用上线都遇到的问题,简直就是三部
曲啊。  

  更多评论

  
#
 
re: 一次性能调优的实战

2009-06-17 10:22 | ufo

(web server软件)UFO不会出现一个字节的内存泄漏和一个线程的不能回收,使用UFO做Web
Server的好处是网站能做得很稳定,永远也不会自己down掉;UFO在托管机房丢包率很高、遭受Hacker攻击、互联网
骨干网被黑等恶劣的环境条件下仍然能很好地运行;UFO在对付Hacker方面(防Hacker弄down和Hacker抓取不该访问的资源)也有足够措
施。

另外,UFO几乎不会进行垃圾回收,消耗CPU很少,在普通的PC
Server上用UFO运行网站,平时CPU占用率<0.1%,最多时也不会超
过5%。您知道,JVM的垃圾回收会导致大量的运算,消耗很多CPU,从而导致Server的负载能力和响应速度下降。UFO在对象管理方面采
用了很好的机制和算法,做得很出色。用UFO运行网站,可以一直保证高负载能力,快速的响应速度和低CPU消耗。发布网址:www.gm365.com

 

http://www.blogjava.net/RongHao/archive/2008/09/01/226068.html

抱歉!评论已关闭.