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); } }