运行结果: 每个10秒钟,打印一次结果。其中报告当前10s中的平均TPS,及平均响应时间RT,以及目前为止最大的响应时间Max RT。 package com.xxx.benchmarker; import java.util.LinkedList; import java.util.Random; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong; /** * BaseBenchMarker(压测统计类) * 业务方需要继承该类,覆盖toBeTestMethod方法即可 * * @author tantexian * @since 2018/7/3 */ public abstract class BaseBenchMarker { public void startup(int threadCount) throws Exception { System.out.printf("start ... threadCount == %d ---->>>>(请覆盖toBeTestMethod()方法为自定义测试逻辑)\n", threadCount); final ExecutorService sendThreadPool = Executors.newFixedThreadPool(threadCount); final StatsBenchmark statsBenchmark = new StatsBenchmark(); final Timer timer = new Timer("BenchmarkTimerThread", true); final LinkedList<Long[]> snapshotList = new LinkedList<Long[]>(); timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { snapshotList.addLast(statsBenchmark.createSnapshot()); if (snapshotList.size() > 10) { snapshotList.removeFirst(); } } }, 1000, 1000); timer.scheduleAtFixedRate(new TimerTask() { private void printStats() { if (snapshotList.size() >= 10) { Long[] begin = snapshotList.getFirst(); Long[] end = snapshotList.getLast(); // index含义:0-代表当前时间,1-发送成功数量 2-发送失败数量 3-接收成功数量 4-接收失败数量 5-发送消息成功总耗时 final long sendTps = (long) (((end[3] - begin[3]) / (double) (end[0] - begin[0])) * 1000L); final double averageRT = ((end[5] - begin[5]) / (double) (end[3] - begin[3])); System.out.printf( "Send TPS: %d Max RT: %d Average RT: %7.3f Send Failed: %d Response Failed: %d\n"// , sendTps// , statsBenchmark.getSendMessageMaxRT().get()// , averageRT// , end[2]// , end[4]// ); } } @Override public void run() { try { this.printStats(); } catch (Exception e) { e.printStackTrace(); } } }, 10000, 10000); for (int i = 0; i < threadCount; i++) { sendThreadPool.execute(new Runnable() { @Override public void run() { while (true) { try { final long beginTimestamp = System.currentTimeMillis(); toBeTestMethod(); statsBenchmark.getSendRequestSuccessCount().incrementAndGet(); statsBenchmark.getReceiveResponseSuccessCount().incrementAndGet(); final long currentRT = System.currentTimeMillis() - beginTimestamp; statsBenchmark.getSendMessageSuccessTimeTotal().addAndGet(currentRT); long prevMaxRT = statsBenchmark.getSendMessageMaxRT().get(); while (currentRT > prevMaxRT) { boolean updated = statsBenchmark.getSendMessageMaxRT().compareAndSet(prevMaxRT, currentRT); if (updated) break; prevMaxRT = statsBenchmark.getSendMessageMaxRT().get(); } } catch (Exception e) { statsBenchmark.getSendRequestFailedCount().incrementAndGet(); e.printStackTrace(); try { Thread.sleep(3000); } catch (InterruptedException e1) { } } } } }); } } /** * 业务使用方,覆盖掉此方法即可以执行自定义压测方法 * * @param * @author tantexian * @since 2018/7/3 */ public void toBeTestMethod() throws Exception { // 随机模拟sleep1~1000毫秒时间 try { final int millis = new Random().nextInt(1000); Thread.sleep(millis); // 模拟如果时间为30毫秒倍数,则失败,抛出异常 if (millis % 500 == 0) { throw new Exception("模拟失败,抛出异常"); } } catch (InterruptedException e) { e.printStackTrace(); } } } class StatsBenchmark { // 1 private final AtomicLong sendRequestSuccessCount = new AtomicLong(0L); // 2 private final AtomicLong sendRequestFailedCount = new AtomicLong(0L); // 3 private final AtomicLong receiveResponseSuccessCount = new AtomicLong(0L); // 4 private final AtomicLong receiveResponseFailedCount = new AtomicLong(0L); // 5 private final AtomicLong sendMessageSuccessTimeTotal = new AtomicLong(0L); // 6 private final AtomicLong sendMessageMaxRT = new AtomicLong(0L); public Long[] createSnapshot() { Long[] snap = new Long[]{// System.currentTimeMillis(),// this.sendRequestSuccessCount.get(),// this.sendRequestFailedCount.get(),// this.receiveResponseSuccessCount.get(),// this.receiveResponseFailedCount.get(),// this.sendMessageSuccessTimeTotal.get(), // }; return snap; } public AtomicLong getSendRequestSuccessCount() { return sendRequestSuccessCount; } public AtomicLong getSendRequestFailedCount() { return sendRequestFailedCount; } public AtomicLong getReceiveResponseSuccessCount() { return receiveResponseSuccessCount; } public AtomicLong getReceiveResponseFailedCount() { return receiveResponseFailedCount; } public AtomicLong getSendMessageSuccessTimeTotal() { return sendMessageSuccessTimeTotal; } public AtomicLong getSendMessageMaxRT() { return sendMessageMaxRT; } }
/** * SendMsgBenchmarker * * @author tantexian * @since 2018/7/3 */ public class SendMsgBenchmarker extends BaseBenchMarker { /** * 也可以通过shell脚本启动该main方法,将threadCount通过args传递进去 * * @author tantexian * @since 2018/7/3 */ public static void main(String[] args) throws Exception { // 启动64个线程 new SendMsgBenchmarker().startup(64); } /** * 业务使用方,覆盖掉此方法即可以执行自定义压测方法 * * @param * @author tantexian * @since 2018/7/3 */ @Override public void toBeTestMethod() throws Exception { // 自定义发送消息方法 sendDataPush(); }