`
vipshichg
  • 浏览: 261853 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

如何进行Java EE性能测试与调优

    博客分类:
  • java
阅读更多

性能测试的目标

性能测试不同于功能测试,不是对与错的检验,而是快与慢的衡量。在进行真正的性能测试之前要先搞清楚目标:

1. 在确定的硬件条件下,可以支持的并发数越大越好,响应时间越快越好。具体需要达到的并发数是多大,要求的响应时间是多快,由产品经理来提出。

2. 在确定的硬件条件下,测试得到最大并发数和相应的响应时间之后。如果增加硬件投入,可以得到怎样的性能提升回报? (系统扩展性和伸缩性测试,Scalability)

这里的硬件条件包括:cpu,memery,I/O,network bandwidth。

性能测试中的基准测试 Benchmarking

与功能测试相似,性能测试也要设计测试用例,不同的是在正式开始你的业务测试用例之前你要先进行一下基准测试。为什么呢?其实就是先要量一下你的硬件的能力,不然,如果你的测试结果不好,你怎么知道是硬件慢还是你的软件的问题。这些硬件测试包括:

1. 网络带宽测试, 你可以通过copy大文件的方式测试你的网络的最大带宽是多少。

2. cpu,你可以利用比较复杂的算法来衡量cpu的快慢

3. memery,这个不用测试,你知道memery的大小

4. IO, 也可以通过copy大文件来测试

这些基准测试用例在后面的调优过程中,还可以用来衡量你修改之后真的变好了吗。

 

设计你的业务测试用例

比较理想的测试用例就是要尽可能模仿真实世界的情况,这往往做不到,尤其是对于新产品来说。你可以先录制一些用户最常用,最典型的case作为起点。

另外,对于并发的概念需要搞清楚。并发用户,通常是指同时在线的用户,这些用户可以能在用你的系统的不同的功能,注意并不是说大家都在做同一件事情。对某一个事务并发请求是指某一个request的并发调用。

对于后一种并发,你往往需要计算在用户量最大的时候,大概大家都集中的在干哪一件事情,这个请求一定要够快才好。

设计好这两种测试用例以后,在后面的调优过程中,他们就成了衡量你的改进的成效的衡量的标尺。

性能调优

性能调优要从底层开始,基本上要从OS开始,到JVM,Cache,Buffer Pool, SQL,DB Schema, 算法。

一次不要改的太多,改一点,测一下,这可是个慢功夫,需要有耐心。

在执行测试的时候还要注意,要遵循相同的过程,系统需要在重启之后先热身再开始真正的测试,不然你会发现你的测试结果很不一样,琢磨不定。

还有,要注意你的客户端的能力,比如JMeter,很需要内存,别因为客户端不行,误以为是你的系统的问题,那就太乌龙了。

在测试调优的时候,需要借助一些监控工具比如JConsole,来监控系统的状况,找到系统的瓶颈,所谓瓶颈,就是最慢的那个部分,也常表现为100%被占满。比如你的内存或者cpu被用尽了。如果cpu和内存还没有用尽,说明他们在等某个资源。这时候需要用profile工具去寻找,比如JProfile,YourKit。

利用性能监控日志

因为性能的问题不是很容易重现,当product环境中遇到性能问题的时候,如果是数据的问题,也许当你把product 数据copy到你的测试环境中,就能重现比较慢点查询,加以改进。但是如果是并发用户或者网络等运行时环境的问题,你就很难重现。这时,如果你能通过日志看到那些关键的响应慢的方法,也许可以帮助你快点找到问题所在。下面的代码可以帮你做到这一点,仅供参考:

  1. import org.slf4j.Logger;   
  2.      
  3.   public class TraceUtil {   
  4.       final Logger logger;   
  5.       final long threshold = 1000;   
  6.       private long begin;   
  7.       private long offtime = 0;   
  8.       private String threadInfo;   
  9.       private String targetId;   
  10.      
  11.       public TraceUtil(Logger logger, Thread thread, String targetId, long begin) {   
  12.           this.logger = logger;   
  13.           this.threadInfo = thread.getId() + "-" + thread.toString();   
  14.           this.targetId = targetId;   
  15.           this.begin = begin;   
  16.       }   
  17.      
  18.       public void trace(String targetEvent) {   
  19.           long duration = System.currentTimeMillis() - begin;   
  20.           long increment = duration - offtime;   
  21.           offtime = duration;   
  22.           float percentage = (float) increment / (float) duration * 100;   
  23.           if (duration > threshold && percentage > 20) {   
  24.               logger.error(   
  25.                       "Response time is too large: [{}], {}/{} ({}), {}, {}",   
  26.                       new String[] { threadInfo + "", increment + "",   
  27.                               duration + "", percentage + "%", targetEvent,   
  28.                               targetId });   
  29.           }   
  30.      
  31.       }   
  32.      
  33.   }  

利用JVM的MXBean找到blocked的点

当你发现JVM占用的cpu很高,而且响应时间比较慢,很可能是被IO或者网络等慢速设备拖住了。也有可能是你的方法中某个同步点(同步方法或者对象)成为性能的瓶颈。这时候你可以利用JVM提供的monitor API来监控:

  1. <%@ page import="java.lang.management.*, java.util.*" %>   
  2.     <%!   
  3.         Map cpuTimes = new HashMap();   
  4.         Map cpuTimeFetch = new HashMap();   
  5.     %>   
  6.        
  7.     <%   
  8.     out.println("Threads Monitoring");   
  9.     long cpus = Runtime.getRuntime().availableProcessors();   
  10.     ThreadMXBean threads = ManagementFactory.getThreadMXBean();   
  11.     threads.setThreadContentionMonitoringEnabled(true);   
  12.     long now = System.currentTimeMillis();   
  13.     ThreadInfo[] t = threads.dumpAllThreads(falsefalse);   
  14.     for (int i = 0; i < t.length; i++) {   
  15.         long id = t[i].getThreadId();   
  16.         Long idObj = new Long(id);   
  17.         long current = 0;   
  18.         if (cpuTimes.get(idObj) != null) {   
  19.             long prev = ((Long) cpuTimes.get(idObj)).longValue();   
  20.             current = threads.getThreadCpuTime(t[i].getThreadId());   
  21.             long catchTime = ((Long) cpuTimeFetch.get(idObj)).longValue();   
  22.             double percent = (double)(current - prev) / (double)((now - catchTime) * cpus * 1000);   
  23.             if (percent > 0 && prev > 0) {  
  24.     out.println("<li>" + t[i].getThreadName()+"#"+t[i].getThreadId() + " Time: " + percent + " (" + prev + ", " + current + ") ");  
  25.     String locked = t[i].getLockInfo()==null?"":t[i].getLockInfo().getClassName();  
  26.     out.println(" Blocked: (" + t[i].getBlockedTime() + ", " + t[i].getBlockedCount() + ", " + locked + ")</li>");  
  27.     }  
  28.         }   
  29.         cpuTimes.put(idObj, new Long(current));     
  30.         cpuTimeFetch.put(idObj, new Long(now));   
  31.     }   
  32.     %> 

同步是性能的一大瓶颈

通过监控发现,大量线程block在一个同步方法上,这样cpu也使不上劲。当你发现性能上不去,IO和网络等慢速设备也不是问题的时候,你就得检查一下是否在某个关键点上使用了同步(synchronizae)。有时候也许是你应用的第三方的jar里面的某个方法是同步的,这种情况下,你就很难找到问题所在。只能在编写代码的时候看一下你引用的方法是否是同步的。

6
4
分享到:
评论

相关推荐

    Java ee性能调优.rar

    Java性能调优 j2ee性能调优....

    JAVA虚拟机性能参数调优指导书.doc

    本文档是Java虚拟机性能参数调优指导书;随着JAVA在应用系统级的项目开发中的使用越来越广泛,虚拟机、垃圾收集、热点编译、J2EE等新技术层出不穷,JAVA作为系统级开发的一个选择的优势也越来越明显,在此同时其不能...

    Java EE图书管理系统测试计划Test Plan.pdf

    Java EE图书管理系统测试计划Test Plan.pdfJava EE图书管理系统测试计划Test Plan.pdfJava EE图书管理系统测试计划Test Plan.pdfJava EE图书管理系统测试计划Test Plan.pdfJava EE图书管理系统测试计划Test Plan.pdf...

    J2EE性能调优.pdf

    J2EE性能调优.pdfJ2EE性能调优.pdfJ2EE性能调优.pdfJ2EE性能调优.pdfJ2EE性能调优.pdfJ2EE性能调优.pdfJ2EE性能调优.pdfJ2EE性能调优.pdfJ2EE性能调优.pdfJ2EE性能调优.pdfJ2EE性能调优.pdf

    10个常见的影响Java EE性能的问题

    本文作者是一名有10多年经验的高级系统架构师,他的主要专业领域是Java EE、中间件和JVM技术。他在性能优化和提升方面也有很深刻的见解,下面欧柏泰克和大家一起分享下他所分析的常见的10个影响Java EE性能问题。

    10个影响Java EE性能的常见问题

    10个影响Java EE性能的常见问题 达内java培训的老师感觉不错,分享给大家

    软件测试工程师成长之路-软件测试方法与技术实践指南Java EE篇

    软件测试工程师成长之路-软件测试方法与技术实践指南Java EE篇

    java ee基础使用教程

    java ee基础使用教程郑阿奇里面含有书中的所有ppt和代码

    精通Java EE项目案例-基于Eclipse Spring Struts Hibernate光盘源码.rar

    精通Java EE项目案例-基于Eclipse Spring Struts Hibernate光盘源码.rar精通Java EE项目案例-基于Eclipse Spring Struts Hibernate光盘源码.rar精通Java EE项目案例-基于Eclipse Spring Struts Hibernate光盘源码....

    基于 java EE .Java权限后台管理系统.pdf

    基于 java EE .Java权限后台管理系统.pdf基于 java EE .Java权限后台管理系统.pdf基于 java EE .Java权限后台管理系统.pdf基于 java EE .Java权限后台管理系统.pdf基于 java EE .Java权限后台管理系统.pdf基于 java ...

    轻量级Java EE企业应用实战 第4版 完整版 pdf 下载

     《轻量级Java EE企业应用实战:Struts2+Spring4+Hibernate整合开发(第4版)》重点介绍如何整合Struts 2.3+Spring 4.0+Hibernate 4.3进行Java EE开发,主要包括三部分。第一部分介绍了Java EE开发的基础知识,以及...

    java ee api

    java ee

    Java EE 7 tutorial 中的examples代码

    Java EE 7 tutorial 中的examples代码,找了很久才找到下来的,跟Java EE 7 tutorial配套使用,是官方的学习资料。

    Practical JSF in Java EE 8 pdf

    Practical JSF in Java EE 8 pdf Master the Java EE 8 and JSF (JavaServer Faces) APIs and web framework with this practical, projects-driven guide to web development. This book combines theoretical ...

    Java EE 7权威指南卷1_1

    本书是一个面向任务的实用指南,通过一系列实用示例来介绍如何开发Java EE 7(java平台企业版7)企业应用。这本书由Oracle的Java EE文档小组成员倾力编写,会让初学者和中缎Java程序员深入了解这个平台。 这个指南包括...

    从Java走向Java+EE+.rar

    第23章 Java EE的测试 319 23.1 开发者为什么需要学习测试 319 23.2 测试的基本概念 320 23.3 利用JUnit进行单元测试 324 23.4 利用StrutsTestCase对Struts进行测试 328 23.5 压力测试和JMeter 334 23.6...

    JavaEE课程设计报告-基于Java EE身体健康管理平台.pdf

    JavaEE课程设计报告-基于Java EE身体健康管理平台.pdfJavaEE课程设计报告-基于Java EE身体健康管理平台.pdfJavaEE课程设计报告-基于Java EE身体健康管理平台.pdfJavaEE课程设计报告-基于Java EE身体健康管理平台....

    java ee API

    java EE,servlet jsp java web 开发的帮助文档,API

Global site tag (gtag.js) - Google Analytics