如何进行Java EE性能测试与调优
作者:网络转载 发布时间:[ 2012/4/23 9:39:52 ] 推荐标签:
利用性能监控日志
因为性能的问题不是很容易重现,当product环境中遇到性能问题的时候,如果是数据的问题,也许当你把product 数据copy到你的测试环境中,能重现比较慢点查询,加以改进。但是如果是并发用户或者网络等运行时环境的问题,你很难重现。这时,如果你能通过日志看到那些关键的响应慢的方法,也许可以帮助你快点找到问题所在。下面的代码可以帮你做到这一点,仅供参考:
import org.slf4j.Logger;
public class TraceUtil {
final Logger logger;
final long threshold = 1000;
private long begin;
private long offtime = 0;
private String threadInfo;
private String targetId;
public TraceUtil(Logger logger, Thread thread, String targetId, long begin) {
this.logger = logger;
this.threadInfo = thread.getId() + "-" + thread.toString();
this.targetId = targetId;
this.begin = begin;
}
public void trace(String targetEvent) {
long duration = System.currentTimeMillis() - begin;
long increment = duration - offtime;
offtime = duration;
float percentage = (float) increment / (float) duration * 100;
if (duration > threshold && percentage > 20) {
logger.error(
"Response time is too large: [{}], {}/{} ({}), {}, {}",
new String[] { threadInfo + "", increment + "",
duration + "", percentage + "%", targetEvent,
targetId });
}
}
}
利用JVM的MXBean找到blocked的点
当你发现JVM占用的cpu很高,而且响应时间比较慢,很可能是被IO或者网络等慢速设备拖住了。也有可能是你的方法中某个同步点(同步方法或者对象)成为性能的瓶颈。这时候你可以利用JVM提供的monitor API来监控:
<%@ page import="java.lang.management.*, java.util.*" %>
<%!
Map cpuTimes = new HashMap();
Map cpuTimeFetch = new HashMap();
%>
<%
out.println("Threads Monitoring");
long cpus = Runtime.getRuntime().availableProcessors();
ThreadMXBean threads = ManagementFactory.getThreadMXBean();
threads.setThreadContentionMonitoringEnabled(true);
long now = System.currentTimeMillis();
ThreadInfo[] t = threads.dumpAllThreads(false, false);
for (int i = 0; i < t.length; i++) {
long id = t[i].getThreadId();
Long idObj = new Long(id);
long current = 0;
if (cpuTimes.get(idObj) != null) {
long prev = ((Long) cpuTimes.get(idObj)).longValue();
current = threads.getThreadCpuTime(t[i].getThreadId());
long catchTime = ((Long) cpuTimeFetch.get(idObj)).longValue();
double percent = (double)(current - prev) / (double)((now - catchTime) * cpus * 1000);
if (percent > 0 && prev > 0) {
out.println("<li>" + t[i].getThreadName()+"#"+t[i].getThreadId() + " Time: " + percent + " (" + prev + ", " + current + ") ");
String locked = t[i].getLockInfo()==null?"":t[i].getLockInfo().getClassName();
out.println(" Blocked: (" + t[i].getBlockedTime() + ", " + t[i].getBlockedCount() + ", " + locked + ")</li>");
}
}
cpuTimes.put(idObj, new Long(current));
cpuTimeFetch.put(idObj, new Long(now));
}
%>
同步是性能的一大瓶颈
通过监控发现,大量线程block在一个同步方法上,这样cpu也使不上劲。当你发现性能上不去,IO和网络等慢速设备也不是问题的时候,你得检查一下是否在某个关键点上使用了同步(synchronizae)。有时候也许是你应用的第三方的jar里面的某个方法是同步的,这种情况下,你很难找到问题所在。只能在编写代码的时候看一下你引用的方法是否是同步的。
相关推荐
更新发布
功能测试和接口测试的区别
2023/3/23 14:23:39如何写好测试用例文档
2023/3/22 16:17:39常用的选择回归测试的方式有哪些?
2022/6/14 16:14:27测试流程中需要重点把关几个过程?
2021/10/18 15:37:44性能测试的七种方法
2021/9/17 15:19:29全链路压测优化思路
2021/9/14 15:42:25性能测试流程浅谈
2021/5/28 17:25:47常见的APP性能测试指标
2021/5/8 17:01:11