疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

让你javaEE 更加流畅的性能调优


 

  Glassfish是目前主流的javaEE应用服务器,目前有很多企业级应用都是运行在GlassFish之上的。因此性能也成为了许多java工程师最考虑的问题。以下,广州java培训机构将为大家介绍一下关于Glassfish性能调优。希望能对你有帮助!

  事实上,Java EE应用程序性能问题对项目和产品是一个非常重要的问题。特别是企业应用程序,并发用户数量多数据传输量大,业务逻辑复杂,占用系统资源多,因此性能问题在企业级应用程序变得越来越重要,它和系统的稳定性有直接联系。更重要的是,性能良好的应用程序在完成相同的任务的条件下,可以占用更少的资源,获得更好的用户体验,换句话说,能够节省成本和消费,更高的利润。

  想要获得更好的性能,需要对原始系统的性能调优。运行在Glassfish JavaEE应用,Glassfish性能调优是一个相对复杂的事情。在调优使用必须承认:JavaEE系统,调优是多层次的。一个JavaEE应用程序是一个很小的整个系统中的一部分。开发人员开发的JavaEE,不管它是JSP或EJB,是运行在JavaEE应用服务器(Glassfish)。应用程序服务器是Java语言,运行在Java虚拟机。Java虚拟机的操作系统也只有一个应用程序只有和其他应用程序(比如Apache)对于操作系统是没有本质区别。虽然操作系统运行在硬件环境,包括CPU、内存、网络卡和硬盘等等。在这么多的层面,每个层面因素将影响整个系统的性能。因此,对一个系统的调优,事实上在同一时间在每个级别调优。JavaEE应用程序性能调优不仅涉及Glassfish,Java语言和操作系统和硬件,但也有一个关系,需要调优有全面的知识和技能。这些不同的维度方法需要综合纵向效果,结合灵活使用,可以快速、有效地定位性能瓶颈。以下是一些具体的案例分析:

  Glassfish性能调优的内存泄漏问题

  一个JavaEE应用程序运行在8 个CPU服务器。运行发现不稳定性能。性能随着时间推移而增加,越来越慢。通过操作系统工具(即mpstat),发现在系统是非常缓慢的时候,只有一个CPU繁忙,其他CPU是空闲的。因此怀疑是Java虚拟机经常回收内存,因为虚拟机回收内存的频率很高,一些恢复算法通常只能运行在一个CPU。由Java虚拟机工具”jstat”可以清楚地看到,一个Java虚拟机内存回收频率非常高,几乎每5秒一次,每一次恢复时间2秒。此外,通过“jstat“输出还发现时间来释放内存非常有限,大多数对象无法被回收。这种现象很大程度上意味着一个内存泄漏。使用Java虚拟机工具“jmap”来获得当前内存映射。发现有许多(超过10000)的会话对象。

  这是不正常的一个现象。一般来说, session对应于一个用户的多次访问,当用户退出的时候,session就应该失效,对象应该被回收。当我们和这个系统的开发工程师了解有关 session的设置,发现当他们部署应用的时候,竟然将session的timeout时间设置为50分钟,并且没有提供logout的接口。这样的设置下,每个session的数据都会保存50分钟才会被回收。根据我们的建议,系统提供了logout的链接,并且告诉用户如果退出应用,应该点击这个 logout的链接;并且将session的timeout时间修改为5分钟。通过几天的测试,证明泄漏的问题得到解决。

  Glassfish性能调优之数据库连接池问题

  一个金融应用程序运行在JavaEE服务器,后台连接Oracle数据库。并发用户数量超过100人,该系统停止响应。通过操作系统级的进程监控工具,这个进程没有被杀掉或挂起,但是CPU利用率的几乎为零。那么是什么原因使系统停止响应用户的请求?我们使用Java虚拟机工具将所有当前线程状态转储,发现JavaEE服务器的处理线程正在等待连接池的数据库连接,而那些获得数据库连接的线程是在一个阻塞状态。数据库管理员应该被要求检查数据库连接的状态,所有的会话是一个死锁状态。显然,这是因为数据库端出现僵局,阻塞数据库操作请求,捆绑所有数据库连接池连接。后续请求从池中获得连接,将阻止在连接池。当解决数据库死锁问题,性能问题是顺利完成或容易解决的。

  Glassfish性能调优之大对象缓存问题

  电信应用运行在64位Java虚拟机上,系统运行得很不稳定,系统经常停止响应。使用进程工具查看,发现进程并没有被杀死或挂起。利用Java虚拟机的工具发现系统在长时间的进行内存回收,内存回收的时间长达15分钟,整个系统在内存回收的时候就像挂起一样。另外还观察到系统使用了12G的内存(因为是 64位虚拟机所以突破了4G内存的限制)。从开发人员那里了解到,这个应用为了提高性能,大量使用了对象缓存,但是事与愿违,在Java中使用过多的内存,虽然在正常运行的时候能够获得很好的性能,但是会大大增加内存回收的时间。特别是对象缓存,本系统使用了8G的缓存空间,共缓存了6000多万个对象,对这些对象的遍历导致了长时间的内存回收。根据我们的建议,将缓存空间减少到1G,并调整回收算法(使用增量回收的算法),使得系统由于内存回收而造成的最大停顿时间减少到4秒,基本满足用户的需求。

  Glassfish性能调优之外部命令问题

  数字校园应用运行在4CPU的Solaris10服务器上,中间件为JavaEE服务器。系统在做大并发压力测试的时候,请求响应时间比较慢,通过操作系统的工具(mpstat)发现CPU使用率比较高。并且系统占用绝大多数的CPU资源而不是应用本身。这是个不正常的现象,通常情况下用户应用的CPU占用率应该占主要地位,才能说明系统是正常工作。通过Solaris 10的Dtrace脚本,我们查看当前情况下哪些系统调用花费了最多的CPU资源,竟然发现最花费CPU的系统调用是“fork”。众所周知, “fork”系统调用是用来产生新的进程,在Java虚拟机中只有线程的概念,绝不会有进程的产生。这是个非常异常的现象。通过本系统的开发人员,我们找到了答案:每个用户请求的处理都包含执行一个外部shell脚本,来获得系统的一些信息。这是通过Java的“Runtime.getRuntime ().exec”来完成的,但是这种方法在Java中非常消耗资源。Java虚拟机执行这个命令的方式是:首先克隆一个和当前虚拟机一样的进程,再用这个新的进程去执行外部命令,最后再退出这个进程。如果频繁执行这个操作,系统的消耗会很大,不仅在CPU,内存操作也很重。用户根据建议去掉这个shell 脚本执行的语句,系统立刻回复了正常。

  Glassfish性能调优之文件操作问题

  内容管理系统(CMS)运行在JavaEE服务器,当系统运行很长一段时间,性能很差,用户请求延迟超过系统启动时间是更大的,而并发用户数量很小,甚至单个用户也很缓慢。通过操作系统工具观察,一切都很正常,CPU利用率不高,IO也不是很大,记忆是非常丰富的,网络几乎没有压力,因为并发用户。不考虑线程互锁的问题,因为单个用户的表现并不好。由Java虚拟机的观察也没有发现任何问题(记忆复苏发生很少)。这让我们可以使用代码跟踪器追踪代码。我们使用Netbeans分析器,跟踪结果很意外,用户请求在90%的时间来创建一个新文件。从系统设计人员理解,这个系统使用一个目录用于存储所有的上传和分享文件,文件以其命名只分化来自其它文件。我们看到的文件在一个目录中,该目录有800000个文件。那时候我们刚刚定位问题:在相同的目录中放置太多的文件,来创建一个新文件,系统开销非常大,例如,以避免重复,文件系统将遍历当前目录文件的名字等等。根据我们的提议,分类的文档存储在不同的目录中,性能得到了较大改善。

  Glassfish性能调优之高速缓存命中率问题

  运行在JavaEE服务器上的ERP系统,在CPU充分利用的情况下性能仍然不太好。从操作系统层面上观察不到什么大问题,而且ERP系统过于复杂,代码跟踪比较困难。于是进行了CPU状态的进一步检查,发现CPU的TLB命中率不是很高,于是对Java虚拟机的启动参数进行了修改,强迫虚拟机使用大尺寸的内存页面,提高TLB的命中率。下面的参数是在Sun的HOTSPOT中调整大尺寸(4M)页面的设置:

  -XX:+AggressiveHeap -XX:LargePageSizeInBytes=256m

  通过调整,TLB命中明显提高,性能也得到近40%的提升。