论坛首页 Java企业应用论坛

hessian服务压力测试

浏览 7600 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-06-23  
SOA
需求:现在的系统有一部分业务是通过hessian的远程服务提供的,为了应对不断的增长的服务器压力,需要对这个提供hessian服务的工程能承受的压力有一个比较详细的了解。

hessian走的http的协议,但是其数据传输跟一般用户发起的http服务还是不一样的,做压力的测试的开源工具还是比较多的,类似jemeter,LoadRunner等都可以,但是这些都没法对hessian服务进行压力测试。

方案1:创建一个web工程,在web工程提供一些http的服务,每个服务会对应的发起一个hessian请求,然后使用某些压力测试工具对这些http进行并发访问。
方案2:自己写java程序,模拟压力测试,然后逐个测试hessian服务。

方案一就不多说了,创建web工程,压力测试我们用的apache的ab test。

方案二:
我的想法是一次性创建X个线程模拟X个并发,然后每个线程循环Y次,每次发起一个hessian的请求,每次执行一次hessian请求,我会创建一个对象收集信息;然后创建一个监控线程,监控这些线程是否都执行完了,如果执行完了就对收集到的数据进行分析。

信息收集对象:
public class StopWatch {
	
	private long startTime;
	private long endTime;
// 一次hessian请求耗时
	private long elapsedTime;
//成功失败
	private boolean status;
	
	public StopWatch(){
		this.startTime = 0L;
		this.endTime = 0L;
		this.elapsedTime = 0L;
		this.status = false;
	}
	
	public long getStartTime() {
		return startTime;
	}
	public void setStartTime(long startTime) {
		this.startTime = startTime;
	}
	public long getEndTime() {
		return endTime;
	}
	public void setEndTime(long endTime) {
		this.endTime = endTime;
	}
	public boolean isStatus() {
		return status;
	}
	public void setStatus(boolean status) {
		this.status = status;
	}
	public long getElapsedTime() {
		return elapsedTime;
	}
	public void setElapsedTime(long elapsedTime) {
		this.elapsedTime = elapsedTime;
	}

}


压力测试主程序:
public class StressTest {
	
	private final static String url1 = "XXXXXXX";
	
	public static void main(String args[]) throws Throwable{
		
		HessianProxyFactory hpf = new HessianProxyFactory();
		hpf.setChunkedPost(false);
		final UserManagerRemote userManagerRemote = (UserManagerRemote)hpf.create(url1);

// 创建收集信息list
		final List<StopWatch> list = new ArrayList<StopWatch>(10000);
//线程数量
		int count = 150;	
		final long start1 = System.currentTimeMillis();
//创建循环栅栏,第一版我是创建了一个监控线程
		final CyclicBarrier barrier = new CyclicBarrier(count, new Runnable(){
				@Override
				public void run() {
					long end1 = System.currentTimeMillis();
//分析收集到的信息
					analyseStopWatch(list, (end1-start1));
				}
			}
		);
		for(int i=0; i<count; i++){
			Thread t = new Thread(
				new Runnable(){
					@Override
					public void run() {
						for(int j=0; j<100; j++){
//创建收集信息对象
							StopWatch sw = new StopWatch();
							long startTime = System.currentTimeMillis();
							sw.setStartTime(startTime);
							try {
								userManagerRemote.get(****L);
								sw.setStatus(true);
							} catch (Throwable e) {
								sw.setStatus(false);
							}
							long endTime = System.currentTimeMillis();
							sw.setEndTime(endTime);
							sw.setElapsedTime(endTime-startTime);
//将收集信息对象添加到list中
							list.add(sw);
						}
						try {
							barrier.await();
						} catch (InterruptedException e) {
							e.printStackTrace();
						} catch (BrokenBarrierException e) {
							e.printStackTrace();
						}
					}
					
				}
			);
			if(i < 29){
				t.setDaemon(true);
			}
			t.start();
		}
		
	}
	
	private static void analyseStopWatch(List<StopWatch> stopWatchs, long totalSpend){
		
		System.out.println("size = "+stopWatchs.size());
		Collections.sort(stopWatchs, new Comparator<StopWatch>(){
			@Override
			public int compare(StopWatch o1, StopWatch o2) {
				Long elapsedTime1 = o1.getElapsedTime();
				Long elapsedTime2 = o2.getElapsedTime();
				return elapsedTime1.compareTo(elapsedTime2);
			}
		});
		int size = stopWatchs.size();
		long min = 0;
		for(StopWatch sw : stopWatchs){
			if(sw.getElapsedTime() > 0){
				min = sw.getElapsedTime();
				break;
			}
		}
		System.out.println("spend time min = "+min+"MS   |   max = "+stopWatchs.get(size-1).getElapsedTime()+"MS");
		int failCount = 0;
		long spendTime = 0L;
		for(StopWatch sw : stopWatchs){
			spendTime +=sw.getElapsedTime();
			if(!sw.isStatus()){
				failCount += 1;
			}
		}
		System.out.println("total spend time = "+totalSpend+"MS");
		System.out.println("total request count = "+size);
		double d1 = totalSpend;
		double d2 = size;
		double averageST = d1/d2;
		System.out.println("average spend time = "+spendTime/size+"MS");
		System.out.println("Transaction Per Second = "+(1000/averageST));
		System.out.println("total fail count = "+failCount);
	}

}
   发表时间:2011-09-28  
这个还比较全
0 请登录后投票
   发表时间:2011-09-28  
JOJYP 写道
这个还比较全


饿,这个帖子终于有人回了。。。。
有个小问题:

// 创建收集信息list 
final List<StopWatch> list = new ArrayList<StopWatch>(10000);
这个地方要用:
List<StopWatch> elapsedTimeList = Collections.synchronizedList(new ArrayList<StopWatch>(10000));
0 请登录后投票
   发表时间:2011-09-30  
都走http这么上层的协议,loadrunner为什么不行?我很想知道
你自己写的代码,和loadrunner的loadgen的实现不就很类似吗?

而且用java写循环并发,先考虑自身的压力吧,还测服务器。
现在大部分的并发程序都用erlang了,如果你想测好,建议用那个语言再写边吧。
0 请登录后投票
   发表时间:2011-10-01  
对过程不感兴趣,就像知道结果。

请求多大数据量,多少并发线程,机器配置,吞吐量、cpu、响应时间和TPS
0 请登录后投票
   发表时间:2011-10-25  
jxdncsl 写道
都走http这么上层的协议,loadrunner为什么不行?我很想知道
你自己写的代码,和loadrunner的loadgen的实现不就很类似吗?

而且用java写循环并发,先考虑自身的压力吧,还测服务器。
现在大部分的并发程序都用erlang了,如果你想测好,建议用那个语言再写边吧。


虽然都走的是http协议,但是数据传输格式跟通用的web请求还是不一样的。

俺不知道loadrunner怎么测试hessian服务,如果仁兄有,还请指教下哈。

用java写循环并发做压力测试这个问题应该不大吧!就几万个请求或者再大些,一般的PC也应付的了。

memcache的国产开源客户端的xmemcached的benchmark测试也是这么搞的。

现在针对高并发确实有很多后台程序是用erlang写的,俺以前公司的广告系统后台是erlang写的,不过俺没有接触过。
0 请登录后投票
   发表时间:2011-10-25  
kimmking 写道
对过程不感兴趣,就像知道结果。

请求多大数据量,多少并发线程,机器配置,吞吐量、cpu、响应时间和TPS


饿,俺当时就是想写个java的程序来针对hessian的服务做压力测试,当时有一些数据,不过我们的要求没那么高,能到一个差不多的数据就行了。
0 请登录后投票
   发表时间:2011-10-25  
没有数据的测试不算测试,,,
0 请登录后投票
   发表时间:2011-10-25  
icanfly 写道
没有数据的测试不算测试,,,


恩,标题有误导了,文章本来想说的其实测试的方案。
0 请登录后投票
   发表时间:2012-03-26  
没有看到压力测试结果,兄台
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics