`
liyiye
  • 浏览: 425114 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

一次性能调优的实战

阅读更多

项目情况:是一个大型公司的内部办公系统,该系统有两个和一般企业应用不太一样的特点:一是用户量非常多,人员数达到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.iteye.com/blog/205731 。分析发现一个工作项提交的操作在连接数据库时被挂起了20分钟!造成了大量线程的排队阻塞。被挂起的原因有很多种。我们采用的方法是将接口拆分和设置事务timeout时间。但是这显然不是一个好方法。最后是去掉所有的synchronized关键字,将同步的问题交由数据库解决,问题解决。

四、反思
1、系统集成商为什么不购买正版?
2、开发平台提供商究竟在项目开发中处于一种什么样的位置?开发平台是否对所有软件开发问题都要负责?
3、开发平台是越封装越快乐吗?还是越封装越丑陋?

分享到:
评论

相关推荐

    性能调优实战记录(doc)

    这次性能调优实战记录展示了从日志分析、内存监控、代码优化到JVM选择等一系列步骤,强调了在性能优化过程中,理解系统行为、定位问题源头、选择合适的工具以及不断迭代改进的重要性。对于从事性能测试和调优的...

    jvm调优实战经验

    - **青年代(Young Generation)**:大部分对象在这里创建并快速死亡,经历一次或几次Minor GC后,存活对象晋升至老年代。 - **老年代(Old Generation)**:长期存活的对象,经历了多次Minor GC后,它们被移动...

    Tomcat性能调优实战总结

    【Tomcat性能调优实战总结】 Tomcat性能调优是一个涉及多方面技术的复杂过程,主要包括对外部环境的调整和Tomcat自身配置的优化。在实际应用中,我们需要通过压力测试来评估系统的性能表现,然后根据测试结果进行...

    Spark性能优化指南.pdf

    例如,当从同一个数据源创建多个RDD时,每创建一个RDD都会触发一次数据读取操作,这显然是低效的。 **示例**:考虑一个简单的例子,需要对HDFS上的文件`hello.txt`执行两次算子操作——`map`和`reduce`。如果按照...

    Hive性能优化

    Hive性能优化是大数据处理中一个非常关键的环节,它能够显著提高查询效率,缩短查询时间。 首先,数据倾斜是导致Hive性能低下的主要原因之一。所谓数据倾斜,是指在MapReduce过程中,数据分布不均匀,导致某些节点...

    Oracle调优实战执行计划

    ### Oracle调优实战执行计划详解 #### 一、执行计划的重要性 执行计划是Oracle数据库引擎在执行SQL语句时所采用的一系列策略和技术的集合,它决定了如何从表或索引中检索数据、如何处理这些数据,以及如何将它们...

    十分简单易懂的Java应用程序性能调优技巧分享

    Java应用程序性能调优是提升软件效率的关键步骤,...总之,Java性能调优是一个系统性的过程,包括了代码优化、JVM配置调整、数据库优化等多个层面。通过结合通用和特定于Java的策略,可以显著提升应用程序的运行效率。

    img JVM调优实战.pdf

    最后,文档中提到的实战篇会介绍具体的调优步骤,包括测试脚本的录制、测试场景的定义、调优方案的选择、JVM监控图的查看以及测试结果的分析。通过这些实际操作,可以进一步理解和掌握JVM调优的技巧和策略。文档的...

    115 案例实战:数十亿数量级评论系统的SQL调优实战(1).pdf

    在这个名为"115 案例实战:数十亿数量级评论系统的SQL调优实战(1)"的PDF中,讨论的是一个针对大规模商品评论系统的SQL优化问题。这个系统处理的数据量极其庞大,达到十亿级别的评论数据,因此采用了分库分表策略,...

    马士兵jvm调优笔记.docx

    - **复制算法**(Copying):将内存分为大小相等的两块,每次只使用其中一块,在垃圾回收时,将还活着的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉。这种算法适用于新生代,因为每次回收都有大量...

    JVM内存模型和性能调优:JVM调优工具详解及调优实战:jstat – 第38篇

    新创建的对象首先被分配到Eden区,经历一次或多次Minor GC后,存活下来的对象会被移到Survivor区,直到最终晋升到老年代。 2. **老年代**(Tenured Generation):存放长期存活的对象,当老年代空间不足时会触发...

    java应用性能内存调优

    Java应用性能调优是一项复杂但非常重要的任务。通过合理的设计、遵循编码规范、正确使用工具和技术,可以在不牺牲功能性的前提下大幅提升系统的性能表现。希望本文提供的指导能够帮助开发者更好地理解和应对性能调优...

    JVM调优攻略.pdf

    5. 经过第一次Minor GC后仍然存活的对象会被移动到Survivor区,并且每次GC后年龄+1。 6. 当对象年龄达到一定阈值时,会被移至老年代。 #### 五、年轻代中的GC 在年轻代中,JVM需要确保To Survivor空间为空。在每次...

    06-VIP-JVM调优实战及常量池详解(1)1

    例如,日志中的“6160K->0K(141824K)”表示在一次GC操作后,年轻代的内存从6160K减少到0K,总容量为141824K。这样的信息有助于判断GC活动是否正常,并据此调整JVM参数以优化性能。 当GC日志过长时,使用第三方工具...

    性能测试-Jmeter.pptx

    【性能测试-Jmeter.pptx】的培训内容涵盖了性能测试的多个重要环节,包括数据制造、性能测试方案设计、脚本执行、性能监控与调优以及编写性能测试报告。以下是对这些知识点的详细阐述: 1. **如何制造数据**: - ...

    JVM 调优之 Eclipse 启动调优实战

    本文将分享一个基于旧版环境(Dell E5410,Intel i3 CPU M 370,2GB内存,32位Windows XP,Java HotSpot Client VM,Eclipse 4.2.0)的JVM调优实战案例,尽管硬件和软件版本已过时,但调优的基本思路和方法仍然具有...

    MSB企业级JVM优化与性能调优课程 解读JVM内部机制-针对性解决企业架构优化问题

    当这一块的内存用完了,就将还存活着的对象复制到另一块上面,然后再把已使用过的内存空间一次清理掉。 - **标记-整理算法**:标记过程同标记-清除算法,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的...

    JVM实战参数调优

    6. **持续监控**:调优并非一次性任务,应持续监控应用性能,随时进行微调。 总结,JVM参数调优和垃圾回收机制是Java性能优化的关键。掌握这些知识,开发者可以更好地理解应用的内存行为,有效提升系统的稳定性和...

    数据库调优及性能问题预防.pptx

    在性能调优方面,提出了“预防措施”、“日常调优”和“故障处理”这三板斧。预防措施包括设计评审,避免不规范配置和低性能SQL上线;日常调优涉及硬件架构优化和业务逻辑优化;而故障处理则强调快速定位问题并采取...

Global site tag (gtag.js) - Google Analytics