自己编写benchmark压测及统计工具类(java)

运行结果: 每个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();
    }

 

转载于:https://my.oschina.net/tantexian/blog/1839432

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值