性能测试和调优实战---jmeter、jamon、jconsole_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > 性能测试和调优实战---jmeter、jamon、jconsole

性能测试和调优实战---jmeter、jamon、jconsole

 2010/11/17 22:48:50  sunqi  http://sunqi.javaeye.com  我要评论(0)
  • 摘要:现在网站高并发情况下,上个关键功能点都需要进行压力测试,进行性能调优,如何去做呢?来个实战吧现在压力测试jmeter使用也非常普遍了,对于一些页面测试的,登录cookie等模拟的直接用jmeter就能做到,也可以用badboy录制脚本就能直接使用,但对于hessian接口的压测就比较麻烦,下面以对hessian接口压测为列jmeter提供了对java等测试的扩展,但需要自己写脚本,建立个java工程,引入可见jmeter充分预留了扩展功能。还有引入依赖的hessian的jar
  • 标签:性能测试 调优

? ?现在网站高并发情况下,上个关键功能点都需要进行压力测试,进行性能调优,如何去做呢?来个实战吧

?? 现在压力测试jmeter使用也非常普遍了,对于一些页面测试的,登录cookie等模拟的直接用jmeter就能做到,也可以用badboy录制脚本就能直接使用,但对于hessian接口的压测就比较麻烦,下面以对hessian接口压测为列

??jmeter提供了对java等测试的扩展,但需要自己写脚本,建立个java工程,引入

?

?

可见jmeter充分预留了扩展功能。还有引入依赖的hessian的jar,以及hessian接口的jar编写脚本如下:

?

//继承AbstractJavaSamplerClient
public class hessianTest extends AbstractJavaSamplerClient{

                //hessian调用地址
	private static String url = "http://10.20.147.182:8080/hessian/remoting/userService";
	MyService collect = null;
	HessianProxyFactory factory = new HessianProxyFactory();
	public int id;
	
	@Override
	public void setupTest(JavaSamplerContext arg0) {
		//获取jmeter传入参数
		 id=arg0.getIntParameter("id");
		try {
			collect = (MyService) factory.create(
					MyService.class, url);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
	}

	@Override
	public SampleResult runTest(JavaSamplerContext arg0) {
		SampleResult sp = new SampleResult();
		sp.sampleStart();
		User rt = null;
		try {
			rt = collect.getUser(id);
		} catch (Exception e) {
			sp.sampleEnd();
			sp.setSuccessful(false);
			return sp;
		}
		sp.sampleEnd();
		if(rt.getId()==id)
			sp.setSuccessful(true);
		else
			sp.setSuccessful(false);
		return sp;
	}

	@Override
	public void teardownTest(JavaSamplerContext context) {
		super.teardownTest(context);
	}

}

?

把此脚本打包jar,连同hessian的jar,以及hessian接口的jar,放入jmeter的lib\ext目录下,这样jmeter才能调用到脚本。启动jmter,新建线程组,java请求和聚合报告如下

?

?

?

java请求中可以看到,刚才新建的脚本,在类名称当中能选择了,id是可以依据需要设置,后台脚本能够动态读取的,这就是需要压力测试的脚本,把此脚本保存在bin目录下,

在调试的时候可以使用在windows下界面,真正压力测试肯定要在lunix下执行


下面直接配置jamon和jconsle,jconse配置很简单,只要在tomcat加上参数

JAVA_OPTS="$JAVA_OPTS -Xms64m -Xmx128m -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1688 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false"

就能在1688端口直接上,监控jvm运行情况

?

?

至于jamon,就需要进行如下操作

?

1、tomcat的server.xml中加上

<Engine name="Catalina" defaultHost="localhost">下面加,这是tomcat6的,其他版本依据其他的配置
?<Valve className="com.jamonapi.http.JAMonTomcatValve"/>

2、lib中加jamon-2.7.jar jamontomcat-2.7.jar

3、webapp加项目jamon,可直接去附件下载


4、hessian接口项目需要加spring配置

<bean
		class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<property name="beanNames">
			<list>
				<value>*Service</value>
			</list>
		</property>
		<property name="interceptorNames">
			<list>
				<value>performanceMonitorInterceptor</value>
			</list>
		</property>
	</bean>
	<bean id="performanceMonitorInterceptor"
		class="org.springframework.aop.interceptor.JamonPerformanceMonitorInterceptor">
		<property name="logTargetClassInvocation" value="true" />
		<property name="trackAllInvocations" value="true" />
	</bean>

?其中的*Service是指拦截的接口,
? log4j.properties需要添加如下配置

log4j.logger.org.springframework.aop.interceptor.JamonPerformanceMonitorInterceptor =TRACE

?

?

这样就能够通过jamon监控每个方法的执行时间了。

如果你的日志调成info级别,你就能看到jamon监控方法执行的日志,如:

2010-11-10 11:46:54,436 TRACE[JamonPerformanceMonitorInterceptor.java:110] : JAMon performance statistics for method [hessian.server.impl.SleepServiceImpl.synchronizedMork]:
JAMon Label=hessian.server.impl.SleepServiceImpl.synchronizedMork, Units=ms.: (LastValue=90117.0, Hits=108.0, Avg=53088.28703703704, Total=5733535.0, Min=3001.0, Max=115330.0, Active=0.0, Avg Active=17.814814814814813, Max Active=30.0, First Access=Wed Nov 10 11:02:44 CST 2010, Last Access=Wed Nov 10 11:46:54 CST 2010)

?

?

启动tomcat,进入jmeter下bin目录执行之前保持的脚本

?

./jmeter -n -t user.jmx -l user.jtl

?

开始压力测试

?

hessian接口的测试代码如下:

	public User getUser(int id) {
		//log.info(" id==" + id);
		sleepService.sleep();
		sleepService.consumeMemery();
		sleepService.synchronizedMork();
		User u = new User();
		return u;
	}



public class SleepServiceImpl implements SleepService{
	private static Object o=new Object();
	private List<User> list=new ArrayList<User>();
	public void sleep() {
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	
	public void consumeMemery(){
		for(int i=0;i<1000;i++){
			list.add(new User());
		}
	}

	public void synchronizedMork() {
		synchronized(this){
			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
	}

}
 

?三个方法分别模拟了响应时间长,内存溢出,锁等情况!直接压就可以发现如下结果

?

?

summary +???? 1 in?? 8.1s =??? 0.1/s Avg:? 8113 Min:? 8113 Max:? 8113 Err:???? 0 (0.00%)
summary +???? 3 in? 16.4s =??? 0.2/s Avg: 13380 Min: 10343 Max: 16419 Err:???? 0 (0.00%)
summary =???? 4 in? 17.3s =??? 0.2/s Avg: 12063 Min:? 8113 Max: 16419 Err:???? 0 (0.00%)
summary +???? 4 in? 28.6s =??? 0.1/s Avg: 24014 Min: 19456 Max: 28574 Err:???? 0 (0.00%)
summary =???? 8 in? 29.3s =??? 0.3/s Avg: 18039 Min:? 8113 Max: 28574 Err:???? 0 (0.00%)
summary +???? 3 in? 37.7s =??? 0.1/s Avg: 34649 Min: 31611 Max: 37687 Err:???? 0 (0.00%)
summary =??? 11 in? 38.3s =??? 0.3/s Avg: 22569 Min:? 8113 Max: 37687 Err:???? 0 (0.00%)

?

?

其中0.1/s Avg就是tps,也就是系统的吞吐量,可见非常的低,查看jconse,

?

名称: http-8080-28
状态:BLOCKED 在 hessian.server.impl.SleepServiceImpl@7d7636ca 上,拥有者: http-8080-26
阻塞总数:2? 等待总数: 1

堆栈追踪:
hessian.server.impl.SleepServiceImpl.synchronizedMork(SleepServiceImpl.java:29)
sun.reflect.GeneratedMethodAccessor71.invoke(Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)

?

当然这些线程信息也可以通过kill -3 javaid查看到

可以看到很多的线程是BLOCKED 的,需要优化,也可以进入jamon,http://ip:端口/jamon

?

?

?

?

?

通过上图,可以看到什么方法非常耗时,就可以进行专门优化,把sleep和synchronizedMork注释,再运行压,

你会发现jconse很快就会报内存溢出,java.lang.OutOfMemoryError: Java heap space

?在lunix下通过top+1你会看到有个cpu使用率在100%左右,那是一直在gc却已经不行了

?

原来是那个consumeMemery在消耗内存,再优化掉后压

你会发现

?

summary + 13977 in?? 3.9s = 3578.3/s Avg:???? 3 Min:???? 0 Max:?? 165 Err:???? 0 (0.00%)
summary + 102067 in? 10.1s = 10154.9/s Avg:???? 2 Min:???? 0 Max:?? 118 Err:???? 0 (0.00%)
summary = 116044 in? 13.9s = 8344.9/s Avg:???? 2 Min:???? 0 Max:?? 165 Err:???? 0 (0.00%)
summary + 107456 in? 10.0s = 10739.2/s Avg:???? 2 Min:???? 0 Max:??? 25 Err:???? 0 (0.00%)
summary = 223500 in? 23.9s = 9349.1/s Avg:???? 2 Min:???? 0 Max:?? 165 Err:???? 0 (0.00%)
summary + 103882 in? 10.0s = 10379.9/s Avg:???? 2 Min:???? 0 Max:??? 29 Err:???? 0 (0.00%)
summary = 327382 in? 33.9s = 9655.6/s Avg:???? 2 Min:???? 0 Max:?? 165 Err:???? 0 (0.00%)

?

tps一下升到了9k多,这样一台机器就能扛住每秒9k的访问量了,那一天能支持多少pv呢?你自己算,当然这是模拟

通过这样循环测试优化,再进行稳定性测试,最终达到你期望的结果

?

?

?

当然还有其他的监控工具,如javamelody,还有jvm的监控jvisualvm等,或者直接用命令监控,如jmap,jstat等等

总之达到你期望的目标,工具是辅助发现问题,优化才是根本

?

发表评论
用户名: 匿名