• 今天写了一个可以测试并发数和运行次数的压力测试代码。(Java)


    今天写了一个可以测试并发数和运行次数的压力测试代码

    1. 介绍一下为什么会写这么一个工具。
    2. 介绍一个这个工具怎么用的。

    背景

    最近在开发CoapServer端,以及模拟设备侧发送数据调用开发好的CoapServer的性能,进行压力测试。

    自己没有找到合适的压力测试的工具,但是测试诉求相对比较简单,觉得用Java可以来控制测试。
    测试维度:

    1. 一共模拟1W台设备,共计发送数据100W次
    2. 模拟多台设备同时发送数据。

    代码和使用

    import org.eclipse.californium.core.CoapClient;
    import org.eclipse.californium.core.CoapResponse;
    import org.eclipse.californium.core.Utils;
    import org.eclipse.californium.elements.exception.ConnectorException;
    
    import java.io.IOException;
    import java.text.NumberFormat;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class PressTestClient {
    
        static int count = 0;
        //总访问量是client_num,并发量是thread_num
        int thread_num = 10;
        int client_num = 1000;
    
        float avg_exec_time = 0;
        float sum_exec_time = 0;
        long first_exec_time = Long.MAX_VALUE;
        long last_done_time = Long.MIN_VALUE;
        float total_exec_time = 0;
    
        String url = "";
        String postData = "";
    
        public PressTestClient(int thread_num, int client_num, String url, String postData) {
    
            this.thread_num = thread_num;
            this.client_num = client_num;
            this.url = url;
            this.postData = postData;
        }
    
    
        public void run() {
    
            final PressTestClient currentObj = this;
    
            final ConcurrentHashMap<Integer, ClientThreadRecord> records = new ConcurrentHashMap<Integer, ClientThreadRecord>();
    
            // 建立ExecutorService线程池
            ExecutorService exec = Executors.newFixedThreadPool(thread_num);
            // thread_num个线程可以同时访问
            // 模拟client_num个客户端访问
            final CountDownLatch doneSignal = new CountDownLatch(client_num);
    
            for (int i = 0; i < client_num; i++) {
    
                Runnable run = new Runnable() {
    
                    public void run() {
    
                        int index = getIndex();
                        long st = System.currentTimeMillis();
    
                        try {
                            //测试的逻辑代码
                            TlsCoAPClient example = new TlsCoAPClient();
                            CoapClient coapClient = example.getClient("device_service");
                            CoapResponse response = null;
                            try {
                                System.out.println("start client request:" +index );
                                response = coapClient.get();
                                System.out.println("device_service: " + Utils.prettyPrint(response));
                                Thread.sleep(100);
                            } catch (ConnectorException | IOException e) {
                                e.printStackTrace();
                            }
    
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
    
                        records.put(index, new ClientThreadRecord(st, System.currentTimeMillis()));
                        doneSignal.countDown();//每调用一次countDown()方法,计数器减1
                    }
                };
                exec.execute(run);
            }
    
            try {
                //计数器大于0 时,await()方法会阻塞程序继续执行
                doneSignal.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            /**
             * 获取每个线程的开始时间和结束时间
             */
            for (int i : records.keySet()) {
                ClientThreadRecord r = records.get(i);
                sum_exec_time += ((double) (r.et - r.st)) / 1000;
    
                if (r.st < first_exec_time) {
                    first_exec_time = r.st;
                }
                if (r.et > last_done_time) {
                    this.last_done_time = r.et;
                }
            }
    
            this.avg_exec_time = this.sum_exec_time / records.size();
            this.total_exec_time = ((float) (this.last_done_time - this.first_exec_time)) / 1000;
            NumberFormat nf = NumberFormat.getNumberInstance();
            nf.setMaximumFractionDigits(4);
    
    
            System.out.println("======================================================");
            System.out.println("Thread Num: " + thread_num + ", Client Count: " + client_num + ".");
            System.out.println("Avg Exec Time:   " + nf.format(this.avg_exec_time) + " s");
            System.out.println("Total Exec Time: " + nf.format(this.total_exec_time) + " s");
            System.out.println("Throughput:      " + nf.format(this.client_num / this.total_exec_time) + " /s");
        }
    
        public static int getIndex() {
            return ++count;
        }
    
        public static void main(String[] args) {
            //总访问量和并发量两重循环,依次增大访问
            //访问量
            for (int j = 500; j < 501; j += 100) {
                //并发量
                for (int i = 500; i < 501; i += 1) {
                    //要测试的URL
                    String url = "http://www.baidu.com/";
                    new PressTestClient(i, j, url, "").run();
                }
            }
            System.out.println("finished!");
        }
    }
    
    class ClientThreadRecord {
        long st;
        long et;
    
        public ClientThreadRecord(long st, long et) {
            this.st = st;
            this.et = et;
        }
    }
    
    

    如何使用?

    1. main方法中的循环此时是控制 运行数和并发数的
    2. 上面run方法,是控制你要测试的代码的。可以自定义。

    效果展示

    运行图

    运行图

  • 相关阅读:
    win7下环境搭建
    python简介-copy
    解决MindManager缺少mfc100u.dll无法启动的难题-转载
    Svn win7系统下状态图标不显示-转载
    【R笔记】order函数例子
    【R笔记】R语言进阶之4:数据整形(reshape)
    【R笔记】R语言利器之ddply
    天池新人实战赛之[离线赛]题目与思路
    第一次写博客
    程序员需要有多懒 ?- cocos2d-x 数学函数、常用宏粗整理
  • 原文地址:https://www.cnblogs.com/dawabigbaby/p/16136273.html
Copyright © 2020-2023  润新知