精华内容
下载资源
问答
  • 并发测试工具

    万次阅读 热门讨论 2019-06-15 14:40:47
    并发测试工具 一、Postman Postman一款非常流行的API调试工具。其实,开发人员用的更多。因为测试人员做接口测试会有更多选择,例如Jmeter、soapUI等。不过,对于开发过程中去调试接口,Postman确实足够的简单方便...

    并发测试工具

    一、Apache Bench简介

    ApacheBench 是 Apache 服务器自带的一个web压力测试工具,简称ab。ab又是一个命令行工具,对发起负载的本机要求很低,根据ab命令可以创建很多的并发访问线程,模拟多个访问者同时对某一URL地址进行访问,因此可以用来测试目标服务器的负载压力。总的来说ab工具小巧简单,上手学习较快,可以提供需要的基本性能指标,但是没有图形化结果,不能监控。

     

    使用说明

    用法很简单,使用ab命令就可以

    参数说明:
    格式:ab [options] [http://]hostname[:port]/path
    ​
    -n requests Number of requests to perform     //本次测试发起的总请求数
    -c concurrency Number of multiple requests to make   //一次产生的请求数(或并发数)
    -t timelimit Seconds to max. wait for responses    //测试所进行的最大秒数,默认没有时间限制。
    -r Don't exit on socket receive errors.     // 抛出异常继续执行测试任务 
    -p postfile File containing data to POST  //包含了需要POST的数据的文件,文件格式如“p1=1&p2=2”.使用方法是 -p 111.txt
    ​
    -T content-type Content-type header for POSTing
    //POST数据所使用的Content-type头信息,如 -T “application/x-www-form-urlencoded” 。 (配合-p)
    -v verbosity How much troubleshooting info to print
    //设置显示信息的详细程度 – 4或更大值会显示头信息, 3或更大值可以显示响应代码(404, 200等), 2或更大值可以显示警告和其他信息。 -V 显示版本号并退出。
    -C attribute Add cookie, eg. -C “c1=1234,c2=2,c3=3” (repeatable)
    //-C cookie-name=value 对请求附加一个Cookie:行。 其典型形式是name=value的一个参数对。此参数可以重复,用逗号分割。
    提示:可以借助session实现原理传递 JSESSIONID参数, 实现保持会话的功能,如-C ” c1=1234,c2=2,c3=3, JSESSIONID=FF056CD16DA9D71CB131C1D56F0319F8″ 。
    -w Print out results in HTML tables  //以HTML表的格式输出结果。默认时,它是白色背景的两列宽度的一张表。
    -i Use HEAD instead of GET
    -x attributes String to insert as table attributes
    -y attributes String to insert as tr attributes
    -z attributes String to insert as td or th attributes
    -H attribute Add Arbitrary header line, eg. ‘Accept-Encoding: gzip’ Inserted after all normal header lines. (repeatable)
    -A attribute Add Basic WWW Authentication, the attributes
    are a colon separated username and password.
    -P attribute Add Basic Proxy Authentication, the attributes are a colon separated username and password.
    -X proxy:port Proxyserver and port number to use
    -V Print version number and exit
    -k Use HTTP KeepAlive feature
    -d Do not show percentiles served table.
    -S Do not show confidence estimators and warnings.
    -g filename Output collected data to gnuplot format file.
    -e filename Output CSV file with percentages served
    -h Display usage information (this message)

    平时使用 -n 说明请求次数,-c 说明并发量就可以了

    结果解析

    Document Path:          /index.html
    Document Length:        17784 bytes     #请求文档大小
     
    Concurrency Level:      10              #并发数
    Time taken for tests:   11.898681 seconds    #全部请求完成耗时
    Complete requests:      100            #全部请求数     
    Failed requests:        0
    Write errors:           0
    Total transferred:      1805900 bytes      #总传输大小
    HTML transferred:       1778400 bytes
    Requests per second:    8.40 [#/sec] (mean)    #每秒请求数(平均)
    Time per request:       1189.868 [ms] (mean)  #每次并发请求时间(所有并发)
    Time per request:       118.987 [ms] (mean, across all concurrentrequests
    Transfer rate:          148.17 [Kbytes/sec] received    #传输速率
     
    Connection Times (ms)           #连接时间
                          min mean[+/-sd]  median(中位值)  max
    Connect: (#连接)     59   73  11.9     72     132
    Processing: (#处理)    86   998538.7     938   2288
    Waiting: (#等待)     63   135 106.8     94    663
    Total:                 155  1072540.6    1004   2362
     
    在一定比例的请求服务时间
     
     50%   1004
     66%   1260
     75%   1452
     80%   1492
     90%   1923
     95%   2078
     98%   2352
     99%   2362
     100%  2362 (longest request)

     

    三、JMeter

    Apache JMeter是Apache组织开发的基于Java的压力测试工具。用于对软件做压力测试,它最初被设计用于Web应用测 试但后来扩展到其他测试领域。 它可以用于测试静态和动态资源例如静态文件、Java 小服务程序、CGI 脚本、Java 对象、数据库, FTP 服务器, 等等。JMeter 可以用于对服务器、网络或对象模拟巨大的负载,来在不同压力类别下测试它们的强度和分析整体性能。另外,JMeter能够对应用程序做功能/回归测试,通过创建带有断言的脚本来验证你的程序返回了你期望的结果。

    使用说明

    由于JMeter功能非常强大,所以此处引用老_张的博客进行说明

    《jmeter:菜鸟入门到进阶系列》

    1、基础介绍 简单介绍jmeter的元件组成,作用等基础知识;

    2、录制脚本 简述了jmeter录制脚本的2种方式;

    3、元件的作用域及执行顺序 jmeter各元件的作用域及执行的顺序;

    4、Sampler之SOAP/XML-RPC Request 取样器中关于SOAP/XML-RPC Request的用法;

    5、Sampler之HTTP请求 取样器中关于HTTP请求的用法;

    6、http请求之content-type 取样器中关于HTTP请求的补充说明;

    7、Sample之JDBC Request 取样器中关于JDBC请求的用法;

    8、JDBC Request之Query Type 取样器中关于JDBC请求的补充说明;

    9、目录结构 jmeter目录结构等简单介绍;

    10、参数化 jmeter参数化的4种方式;

    11、关联之正则表达式提取器 jmeter关联之正则表达式提取器的用法;

    12、关联之XPath Extractor jmeter关联之XPath Extractor的用法;

    13、配置元件之计数器 jmeter配置元件中关于计数器的用法;

    14、配置元件之HTTP属性管理器 jmeter配置元件中关于http属性管理器的用法;

    15、函数助手 jmeter内置函数助手的简单介绍;

    16、定时器 jmeter八大元件之定时器的介绍;

    17、断言 jemter八大元件之断言的介绍;

    18、逻辑控制器 jmeter八大元件之逻辑控制器的介绍;

    19、常见问题及解决方法 jmeter使用过程中常见问题及解决方案的说明;

    20、阶梯式加压测试 jmeter扩展插件Stepping Thread Group的简单介绍;

    21、jmeter常用插件介绍 jmeter插件Transactions per Second、Response Times Over Time、PerfMon Metrics Collector的下载安装及使用;

    22、内存溢出原因及解决方法 关于jmeter做压力负载测试时候遇到内存溢出的原因和解决方法;

    23、jmeter分布式测试 关于高并发情况下分布式测试的一些技术点和注意事项;

    24、dubbo接口测试 利用jmeter的dubbo插件进行dubbo接口测试和性能测试;

    25、linux环境运行jmeter并生成报告 linux环境,非GUI模式运行jmeter脚本进行性能测试,并生成测试报告的介绍;

    26、jmeter生成HTML格式性能测试报告 jmeter生成HTML格式的性能测试报告的2种方式,以及可视化图表解析内容;

    结果解析

    展开全文
  • 系统上线之前需要压力测试,本文以“模拟大量微信小程序用户对平台进行并发访问的性能测试”为案例说明。 一、用程序生成访客数据,最好是项目中在用编程语言,我这里用的是JAVA;因为是模拟小程序用户,所以需要...

    系统上线之前需要压力测试,本文以“模拟大量微信小程序用户对平台进行并发访问的性能测试”为案例说明。

     

    一、用程序生成访客数据,最好是项目中在用编程语言,我这里用的是JAVA;因为是模拟小程序用户,所以需要生成openid、nickname、mobileno、sex等和微信相关联的用户假数据。

    二、将用户数据导入到被测试平台的数据库中,同时将配置信息生成文本文件,以便测试工具使用,这里用的是JMeter。

     

    三、配置好JMeter参数(参考https://blog.csdn.net/pharos/article/details/88934627

    四、访问接口数据参数化,这里接口方式基本采用前端向后端POST JSON数据的格式;所以需要在BodyData中设置。

     

    五、配置好后生成jmx数据文件,上传到Linux服务器端进行压测。

    展开全文
  • 并发编程11-测试并发程序

    千次阅读 2015-02-16 15:25:10
    - 安全性 并发不会造成状态错误。 - 活跃度 主要是性能测试 - 吞吐量 段时间定资源内可以处理的任务数量 - 响应性 从请求到完成一些动作之前的延迟(等待执行的时间) - 可伸缩性 增加资源,提高性能

    测试的两个方面:
    - 安全性 并发不会造成状态错误。
    - 活跃度 主要是性能测试
    - 吞吐量 段时间定资源内可以处理的任务数量
    - 响应性 从请求到完成一些动作之前的延迟(等待执行的时间)
    - 可伸缩性 增加资源,提高性能

    正确性测试

    所有加入队列的都会被执行:
    一般的可行的办法是把加入队列的列表和消费的列表保存起来进行比较。但是因为会设计资源的并发,影响对本身的测试,比较好的办法是在队列中加入唯一的id,然后对id求和,消费时同样求和,来比较结果。这样能最小的影响实际要测试的结果。

    public class PutTakeTest {
        private static final ExecutorService pool = Executors.newCachedThreadPool();
        private final AtomicInteger putSum = new AtomicInteger(0);
        private final AtomicInteger takeSum = new AtomicInteger(0);
        private final int nTrials, nPairs;
        private final BlockingQueue<Integer> queue;
    
        public static void main(String[] args) {
            new PutTakeTest(10000).test();
        }
    
        public PutTakeTest(int nTrials){
            nPairs = 10;    // 生产者及消费者的个数
            this.nTrials = nTrials;     // 每次生产或者消费多少个
            queue = new ArrayBlockingQueue<Integer>(10);
        }
    
        public void test(){
            for (int i = 0; i < nPairs; i++) {
                pool.execute(new Producer());
                pool.execute(new Consumer());
            }
            pool.shutdown();
            try {
                pool.awaitTermination(10, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(putSum.get());
            System.out.println(takeSum.get());
        }
    
        class Producer implements Runnable{
            @Override
            public void run() {
                int sum = 0;
                try {
                    for (int i = 0; i < nTrials; i++) {
                        int seed = new Random().nextInt(10000);     // 随机数,用来做sum,最后跟消费者的sum做比较来确定所有入队的都已经被出队消费
                        sum += seed;
                        queue.put(seed);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                putSum.getAndAdd(sum);
            }
        }
    
        class Consumer implements Runnable{
    
            @Override
            public void run() {
                int sum = 0;
                try {
                    for (int i = 0; i < nTrials; i++) {
                        int seed = queue.take();
                        sum += seed;
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                takeSum.getAndAdd(sum);
            }
        }
    }

    按照上面的代码,实际上出于并行状态的线程并不多,可以使用关卡这种类型的信号量,来让所有的线程同时启动,再同时计算,提升并发的操作。

    性能

    吞吐量
    基于上面的代码,其实在最开始和最后加入时间差的计算就可以粗略估算了
    另外还可以借助关卡的特性,在最后回调的时候得到时间
    响应性
    即完成一个任务所需要的时间

    性能测试陷阱

    如果测试过程中恰巧多次出发了垃圾回收,那么就有可能把gc的时间算到实际运行的实践中。解决办法
    - 使用-verbose:gc来停止垃圾回收的运行
    - 第二种就是运行足够长的时间了
    另外动态编译也可能会造成数据的不准确,可以使用-xx:+PrintCompilation来查看动态编译的时间,长时间运行测试程序,减少动态编译的影响
    另外要考虑不且实际的竞争程度, 影响吞吐量通常是因为边界清晰小人物,大部分的时间都来源于上线问切换,而对于一些锁竞争比较多的程序可能影响最大的是锁竞争的程度,要根据不同情况制定具体的策略。

    代码检查

    • 调用Thread.run,应该是.start
    • 显示锁未释放
    • 空synchronized块
    • 双检查锁, 因为可见性的问题及重排序的问题
    • 从构造函数中启动线程,造成了this的溢出
    • notify通常伴随着状态改变使用
    • wait方法通常会出现在持有锁,循环以及含有测试某个状态的谓词(if())
    • Thread.sleep会持有锁会对活跃度造成影响要注意
    • 忙等待 while(a.equals(“”))这样的结果,如果域不是volatile的可能不会及时得到状态变更,可以使用锁通知等更好的方式。
    展开全文
  • 并发程序测试 编写并发程序时候,可以采取和串行程序相同的编程方式。唯一的难点在于,并发程序存在不确定性,这种不确定性会令程序出错的地方远比串行程序多,出现的方式也没有固定规则。这对程序的应用会造成...

    并发程序的测试

    编写并发程序时候,可以采取和串行程序相同的编程方式。唯一的难点在于,并发程序存在不确定性,这种不确定性会令程序出错的地方远比串行程序多,出现的方式也没有固定规则。这对程序的应用会造成一些困难,那么如何在测试中,尽可能的暴露出这些问题,并且了解其性能瓶颈,这也是对开发者带来新的挑战。

    本篇基于多线程知识,梳理一些多线程测试需要掌握的方法和原则,以期望可能的在开发阶段,就暴露出并发程序的安全性和性能问题,为多线程能够高效安全的运行提供帮助。

    分类

    并发程序中潜在错误的发生并不具有确定性,而是随机的。

    并发测试大致可以分为两类:安全性测试与活跃性测试。

    安全性测试我们可以定义为“不发生任何错误的行为”,也可以理解为保持一致性。比如i++操作,但单线程情况下,循环20次,i=20,可是在多线程情况下,如果总共循环20次,结果不为20,那么这个结果就是错误的,说明出现了错误的线程安全问题。我们在测试这种问题的时候,必须要增加一个”test point”保证其原子性同时又不影响程序的正确性。以此为判断条件执行测试代码,关于“test point”如何做,我们后续再讨论。

    活跃性测试定义为“某个良好的行为终究会发生”,也可以为理解为程序运行有必然的结果,不会出现因某个方法阻塞,而运行缓慢,或者是发生了线程死锁,导致一直等待的状态等。

    与活跃性测试相关的是性能测试。主要有以下几个方面进行衡量:吞吐量,响应性,可伸缩性。

    安全性测试:通常会采用测试不变性条件的形式,即判断某个类的行为是否与其规范保持一致

    活跃性测试:进展测试和无进展测试两方面,这些都是很难量化的(性能:即吞吐量,响应性,可伸缩性测试)

    基本概念

    吞吐量:一组并发任务中已完成任务所占的比例。或者说是一定时间内完成任务的数量。

    响应性:请求从发出到完成之间的时间

    可伸缩性:在增加更多资源(CPU,IO,内存),吞吐量的提升情况。

    一、正确性测试

    重点:找出需要检查的不变性条件和后验条件

    安全性测试,如前面所说是“不发生任何错误的行为”,也是要对其数据竞争可能引发的错误进行测试。这也是我们需要找到一个功能中并发的的“test point”,并对其额外的构造一些测试。而且这些测试最好不需要任何同步机制。

    我们通过一个例子来进行说明。

    比如ArrayBlockingQueue,我们知道这个class是采用一个有界的阻塞队列来实现的生产-消费模式的。如果对其测试并发问题的,重要的就是对put和take方法进行测试,一种有效的方法就是检查被放入队列中和出队列中的各个元素是否相等。如果出现数据安全性的问题,那么必然入队列的值和出队列的值没有发生对应,结果也不尽相同。比如多线程情况下,我们把所有入列元素和出列元素的校检和进行比较,如果二者相等,那么表明测试成功。

    为了保证其能够测试到所有要点,需要对入队的值进行随机生成,令每次测试得到的结果不尽相同。另外为了保证其公平性,要保证所有的线程一起开始运算,防止先进行的程序进行串行运算。

    1、对基本单元的测试——串行的执行

    public class BoundedBufferTests {
        
        @Test
        public void testIsEmptyWhenConstructed(){
            BoundedBuffer<String> bf = new BoundedBuffer<String>(10);
            assertTrue(bf.isEmpty());
        }
        
        @Test
        public void testIsFullAfterPuts() throws InterruptedException{
            BoundedBuffer<String> bf = new BoundedBuffer<String>(10);
            for (int i=0; i<10; i++){
                bf.put("" + i);
            }
            assertTrue(bf.isFull());
            assertTrue(bf.isEmpty());
        }
    }
    

    2、对阻塞操作的测试

    每个测试必须等他创建的所有线程结束后才可以结束(join)

    要测试一个方法的阻塞行为,类似于测试一个抛出异常的方法:如果这个方法可以正常返回,那么就意味着测试失败。

    在测试方法的阻塞行为时,将引入额外的复杂性:当方法被成功地阻塞后,还必须使方法解除阻塞。(中断)

    public void testTaskBlocksWhenEmpty(){
        final BoundedBuffer<Integer> bb = new BoundedBuffer<>(10);
        Thread taker = new Thread(){
            @Override
            public void run() {
                try {
                       int unused =  bb.take();
                    fail(); //不应执行到这里
                } catch (InterruptedException e) {
                }
            }
        };
        try {
            taker.start();
            Thread.sleep(1000);
            taker.interrupt();
            taker.join(2000); //保证即使taker永久阻塞也能返回
            assertFalse(taker.isAlive());
        } catch (InterruptedException e) {
            fail();
        }
    }
    

    3、安全性测试

    构建对并发类的安全性测试中,需要解决的关键问题在于,要找出那些容易检查的属性,这些属性在发生错误的情况下极有可能失败,同时又不会使得错误检查代码人为地限制并发性。理想的情况是,在测试属性中不需要任何同步机制

    例:通过计算入列和出列的校验和进行检验(使用栅栏保证线程均运行到可检验处再检验)

    public class PutTakeTest extends TestCase {
          protected static final ExecutorService pool = Executors
                        .newCachedThreadPool();
          protected CyclicBarrier barrier;
          protected final BoundedBuffer<Integer> bb;
          protected final int nTrials, nPairs;
          protected final AtomicInteger putSum = new AtomicInteger(0);
          protected final AtomicInteger takeSum = new AtomicInteger(0);
    
          public static void main(String[] args) throws Exception {
                 new PutTakeTest(10, 10, 100000).test(); // sample parameters
                 pool.shutdown();
          }
    
          public PutTakeTest(int capacity, int npairs, int ntrials) {
                 this.bb = new BoundedBuffer<Integer>(capacity);
                 this.nTrials = ntrials;
                 this.nPairs = npairs;
                 this.barrier = new CyclicBarrier(npairs * 2 + 1);
          }
    
          void test() {
                 try {
                        for (int i = 0; i < nPairs; i++) {
                               pool.execute(new Producer());
                               pool.execute(new Consumer());
                        }
                        barrier.await(); 
                        barrier.await(); 
                        assertEquals(putSum.get(), takeSum.get());
                 } catch (Exception e) {
                        throw new RuntimeException(e);
                 }
          }
    
          class Producer implements Runnable {
                 public void run() {
                        try {
                               barrier.await();
                               int seed = (this.hashCode() ^ (int) System.nanoTime());
                               int sum = 0;
                               for (int i = nTrials; i > 0; --i) {
                                      bb.put(seed);
                                      sum += seed;
                                      seed = xorShift(seed);
                               }
                               putSum.getAndAdd(sum);
                               barrier.await();
                        } catch (Exception e) {
                               throw new RuntimeException(e);
                        }
                 }
          }
    
          class Consumer implements Runnable {
                 public void run() {
                        try {
                               barrier.await();
                               int sum = 0;
                               for (int i = nTrials; i > 0; --i) {
                                      sum += bb.take();
                               }
                               takeSum.getAndAdd(sum);
                               barrier.await();
                        } catch (Exception e) {
                               throw new RuntimeException(e);
                        }
                 }
          }
    
          static int xorShift(int y) {
                 y ^= (y << 6);
                 y ^= (y >>> 21);
                 y ^= (y << 7);
                 return y;
          }
    }
    

    testLeak方法将多个大型对象插入到一个有界缓存中,然后将它们移除。第2个堆快照中的内存用量应该与第1个堆快照中的内存用量基本相同。

    然而,doExtract如果忘记将返回元素的引用置为空(items[i] = null),那么在两次快照中报告的内存用量将明显不同。(这是为数不多几种需要显式地将变量置空的情况之一。大多数情况下,这种做法不仅不会带来帮助,甚至还会带来负面作用。)

    4、资源管理测试

    对于任何持有或管理其他对象的对象,都应该在不需要这些对象时销毁对它们的引用

    例:使用堆检验工具对内存资源使用进行检验

    5、使用回调

    可以通过自定义扩展类来进行相关测试

    public class TestingThreadFactory implements ThreadFactory {
        public final AtomicInteger numCreated = 
                new AtomicInteger(); //记录创建的线程数
        private final ThreadFactory factory = 
                Executors.defaultThreadFactory();
        
        @Override
        public Thread newThread(Runnable r) {
            numCreated.incrementAndGet();
            return factory.newThread(r);
        }
    }
    
    public class TestThreadPool extends TestCase {
    
        private final TestingThreadFactory threadFactory = new TestingThreadFactory();
    
        public void testPoolExpansion() throws InterruptedException {
            int MAX_SIZE = 10;
            ExecutorService exec = Executors.newFixedThreadPool(MAX_SIZE);
    
            for (int i = 0; i < 10 * MAX_SIZE; i++)
                exec.execute(new Runnable() {
                    public void run() {
                        try {
                            Thread.sleep(Long.MAX_VALUE);
                        } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                        }
                    }
                });
            for (int i = 0;
                 i < 20 && threadFactory.numCreated.get() < MAX_SIZE;
                 i++)
                Thread.sleep(100);
            assertEquals(threadFactory.numCreated.get(), MAX_SIZE);
            exec.shutdownNow();
        }
    }
    

    6、产生更多的交替操作

    使用yield、sleep命令更容易使错误出现

    public synchronized void transferCredits(Account from,
                                             Account to,
                                             int amount) {
        from.setBalance(from.getBalance() - amount);
        if (random.nextInt(1000) > THRESHOLD)
            Thread.yield();//切换到另一线程
        to.setBalance(to.getBalance() + amount);
    }
    

    二、性能测试

    性能测试的目标:

    衡量典型测试用例中的端到端性能,获得合理的使用场景

    根据经验值来调整各种不同的限值,如线程数量,缓存容量等

    1、计时器

    通过增加计时器,并改变各个参数、线程池大小、缓存大小,计算出运行时间

    计时器

    • 在 PutTakeTest 中增加计时功能
    public class TimedPutTakeTest extends PutTakeTest {
           private BarrierTimer timer = new BarrierTimer();
    
           public TimedPutTakeTest(int cap, int pairs, int trials) {
                  super(cap, pairs, trials);
                  barrier = new CyclicBarrier(nPairs * 2 + 1, timer);
           }
    
           public void test() {
                  try {
                         timer.clear();
                         for (int i = 0; i < nPairs; i++) {
                                pool.execute(new PutTakeTest.Producer());
                                pool.execute(new PutTakeTest.Consumer());
                         }
                         barrier.await();//等待所有线程都准备好后开始往下执行
                         barrier.await();//等待所有线都执行完后开始往下执行
                         //每个元素完成处理所需要的时间
                         long nsPerItem = timer.getTime() / (nPairs * (long) nTrials);
                         System.out.print("Throughput: " + nsPerItem + " ns/item");
                         assertEquals(putSum.get(), takeSum.get());
                  } catch (Exception e) {
                         throw new RuntimeException(e);
                  }
           }
    
           public static void main(String[] args) throws Exception {
                  int tpt = 100000; // 每对线程(生产-消费)需处理的元素个数
                  //测试缓存容量分别为1、10、100、1000的情况
                  for (int cap = 1; cap <= 1000; cap *= 10) {
                         System.out.println("Capacity: " + cap);
                         //测试工作线程数1、2、4、8、16、32、64、128的情况
                         for (int pairs = 1; pairs <= 128; pairs *= 2) {
                                TimedPutTakeTest t = new TimedPutTakeTest(cap, pairs, tpt);
                                System.out.print("Pairs: " + pairs + "\t");
    
                                //测试两次                         
                                t.test();//第一次
                                System.out.print("\t");
                                Thread.sleep(1000);
    
                                t.test();//第二次
                                System.out.println();
                                Thread.sleep(1000);
                         }
                  }
                  PutTakeTest.pool.shutdown();
           }
    
           //关卡动作,在最后一个线程达到后执行。在该测试中会执行两次:
           //一次是执行任务前,二是所有任务都执行完后
           static class BarrierTimer implements Runnable {
                  private boolean started;//是否是第一次执行关卡活动
                  private long startTime, endTime;
    
                  public synchronized void run() {
                         long t = System.nanoTime();
                         if (!started) {//第一次关卡活动走该分支
                                started = true;
                                startTime = t;
                         } else
                                //第二次关卡活动走该分支
                                endTime = t;
                  }
    
                  public synchronized void clear() {
                         started = false;
                  }
    
                  public synchronized long getTime() {//任务所耗时间
                         return endTime - startTime;
                  }
           }
    }
    

    2、多种算法的比较

    使用不同的内部实现算法,找出具有更高的可伸缩性的算法

    BoundedBuffer性能不高的主要原因:put和take操作分别都有多个操作可能遇到竞争——获取一个信号量,获取一个锁、释放信号量
    在测试的过程中发现LinkedBlockingQueue的伸缩性好于ArrayBlockingQueue,这主要是因为链接队列的put和take操作允许有比基于数组的队列更好的并发访问,好的链接队列算法允许队列的头和尾彼此独立地更新。LinkedBlockingQueue中好的并发算法抵消了创建节点元素的开销,那么这种算法通常具有更高的可伸缩性。这似乎与传统性能调优相违背

    2、多种算法的比较

    3、响应性衡量

    某个动作经过多长时间才能执行完成,这时就要测量服务时间的变化情况

    除非线程由于密集的同步需求而被持续的阻塞,否则非公平的信号量通常能实现更好的吞吐量,而公平的信号量则实现更低的变动性(公平性开销主要由于线程阻塞所引起)

    所谓的公平信号量是获得锁的顺序与线程启动顺序有关,但不代表100%地获得信号量,仅仅是在概率上能得到保证。而非公平信号量就是无关的了。
    缓存过小,将导致非常多的上下文切换次数,这即是在非公平模式中也会导致很低的吞吐量。

    因此,除非线程由于密集的同步需求而被持续地阻塞,否则非公平的信号量通常能实现更好的吞吐量,而公平的信号量则实现更低的变动性。

    因为这些结果之间的差异非常大,所以Semaphore要求客户选择针对哪个特性进行优化。

    3、响应性衡量

    三、避免性能测试的陷阱

    1、垃圾回收

    保证垃圾回收在执行测试程序期间不被执行,可通过-verbose:gc查看垃圾回收信息。
    保证垃圾回收在执行测试程序期间执行多次,可以充分反映出运行期间的内存分配和垃圾回收等开销。

    2、动态编译

    可以让测试程序运行足够长时间,防止动态编译对测试结果产生的偏差。
    在HotSpot中设置 -xx:+PrintCompilation,在动态编译时输出一条信息

    3、对代码路径不真实采样

    动态编译可能会让不同地方调用的同一方法生成的代码不同
    测试程序不仅要大致判断某个典型应用程序的使用模式,还要尽量覆盖在该应用程序中将执行的代码路径集合

    4、不真实的竞争程度

    不同的共享数据和执行本地计算的比例,将表现出不同的竞争程度,也就有不同的性能和可伸缩性

    5、无用代码的消除

    编译器可能会删除那些没有意义或不会产生结果或可预测结果的代码
    使结果尽量是不可预测的

    四、其他测试方法

    代码审查(人工检查代码),竞态分析工具(FindBugs,CheckStyle),面向方面的测试技术,分析与检测工具(jvisualvm)

    静态分析工具

    不一致的同步

    调用Thread.run

    未被释放的锁

    空的同步块

    双重检查加锁

    在构造函数中启动另一个线程

    通知错误

    条件等待中的错误

    对Lock和Condition的误用

    在休眠或者等待的同时持有一个锁

    自旋循环

    拓展阅读

    junitperf

    性能测试

    参考资料

    《Java并发编程实战》

    第十二章:并发程序的测试——Java并发编程实战

    测试并发程序

    java多线程——并发测试

    大话程序猿眼里的高并发(下)

    https://juejin.im/post/5b067702f265da0de101103e

    https://wenku.baidu.com/view/9a5293197cd184254b353558.html

    https://segmentfault.com/q/1010000010624641

    http://www.mamicode.com/info-detail-1600606.html

    目录

    java多线程并发之旅-01-并发概览

    展开全文
  • 【绿色版】并发连接测试程序... 唯一的希望是,如果你有好的改进建议,希望你能联系QQ:154948101(敲门暗号:“西岭风清-并发连接小程序”)或邮箱 xmwen(at)126(dot)com。 ------------ By 西岭风清 / 2012.11.25
  • 一个微信小程序,同时只能有5个网络请求连接。 我看到开发文档这样说 wx.request发起的是https请求。一个微信小程序,同时只能有5个网络请求连接。 那么,能支持上千个用户同时并发请求吗? 我要做的是需要不断的...
  • 简单的并发测试以及线程监控

    千次阅读 2017-02-15 00:57:33
    并发测试 ab测试工具 JMeter测试工具 Eclipse设置程序可用内存 jvisualvm监控线程
  • 并发程序测试测试并发程序时,所面临的主要挑战在于:潜在错误的发生并不具有确定性,而是随机的。要在测试中将这些故障暴露出来,就需要比普通的串行程序测试覆盖更广的范围并且执行更长的时间。在进行安全性...
  • 负载测试(loading test)、压力测试(stress test)、性能测试(performance test)异同 ...性能测试又称多用户并发性能测试。 我们知道,软件总是运行在一定的环境下,这种环境包括:支撑软件运...
  • 微信小程序怎么性能测试

    千次阅读 2021-01-07 20:51:25
    这样往往会导致性能测试工具无法压测到应用的后台服务,这里用华为云性能测试测试服务 CPTS工具为实践案例,帮助测试攻城狮们快速压测小程序性能 测试步骤: 1、登陆华为云性能测试服务控制台,并进入测试工程...
  • Jmeter小程序压力测试案例

    千次阅读 2020-07-16 16:22:15
    进行有压力测试压力测试思路使用Jmeter,模拟500名真实用户,在120秒、60秒内,请求小程序主要页面共18个接口两遍,然后分析Jmeter提供的测试报告;具体操作1-下载安装Jmeter(我使用的是Jmeter5.1.1),这个网上资源...
  • 微信小程序性能测试

    千次阅读 2019-01-03 10:34:46
    通过微信的Oauth进行认证这样往往会导致性能测试工具无法压测到应用的后台服务,这里用华为云性能测试测试服务 CPTS 工具为实践案例,帮助测试攻城狮们快速压测小程序性能。 测试步骤: 1、登陆华为云性能测试服务...
  • 一个简单的HTTP并发测试程序

    千次阅读 2011-09-21 14:16:00
    //设置线程栈大小,这里设置成了1M,这个可能需要根据情况调,最小不能小于PTHREAD_STACK_MIN,如果太有可能出现栈溢出 pthread_attr_getstacksize(&thread_attr, &stack_size); printf("New stack size is %u; ...
  • Jmeter并发测试

    万次阅读 多人点赞 2018-07-30 15:22:00
    Jmeter并发测试 Jmeter是一个非常好用的压力测试工具。 Jmeter用来做轻量级的压力测试,非常合适,只需要十几分钟,就能把压力测试需要的脚本写好。 阅读目录 什么是压力测试  做压力测试的常用工具 做压力...
  • 小程序并发限制由来已久,从刚发布时的 5 并发,到后来的 10 并发,同时发出的请求数若超出这个限制则将被残忍抛弃,由此催生了很多开发者在自己的项目中造了「请求排队」的轮子。然而事实上,早在一年半以前,该...
  • 网站并发测试工具介绍

    千次阅读 2010-11-23 10:41:00
    网站性能并发测试工具
  • postgres服务并发测试

    千次阅读 2016-05-31 14:11:07
    postgres服务并发测试存在的问题 执行大表的全表查询(select *)进程被kill; 创建GIST、GIN等索引进程被kill; 原因: Linux 内核根据应用程序的要求分配内存,绝大部分应用程序不会同时使用全部内存,为了提高...
  • 并发压力测试

    千次阅读 2018-06-12 20:20:29
     1)帮助我们了解服务器的性能以及并发 2)帮助我们查找程序问题 3)帮助我们了解网站的并发量 4)了解业务系统的瓶颈 5)了解服务器硬件的瓶颈使用apache的ab.exe进行压力测试通过上面的用法介绍可以得知,ab...
  • 微信小程序该如何测试

    千次阅读 多人点赞 2020-08-26 17:21:53
    今天大湿给大家带来了小程序该如何测试。 全文共2115字,阅读需要13分钟 1.什么是小程序 英文名 Mini Program 是一种不需要下载安装即可使用的应用,是内嵌在微信 APP 里面的一款新形态软件。 它实现了应用“触手可...
  • 性能测试又称多用户并发性能测试。 对于性能测试,我们必须要清晰地理解这些概念。执行性能测试,性能瓶颈分析路径:服务器硬件瓶颈-〉网络瓶颈(对局域网,可以不考虑)-〉服务器操作系统瓶颈(参数配置)-〉中间件...
  • 网站性能并发测试工具

    万次阅读 2016-06-22 10:54:50
     我推荐各位Web 2.0开发测试人员使用Microsoft 的Web Application Stress Tool这个工具软件,这个微软提供的工具仅9.58M,很小巧且实用。虽然功能上比不了专业的LoadRunner,但LoadRunner体积庞 大,价格不菲,...
  • 如何测试微信小程序性能?

    千次阅读 2019-01-03 09:55:52
    这样往往会导致性能测试工具无法压测到应用的后台服务,这里用华为云性能测试服务 CPTS工具为实践案例,帮助测试攻城狮们快速压测小程序性能。 测试步骤: 1、登陆华为云性能测试服务控制台,并进入测试工程页面 2...
  • 公司新项目组开发一款微信小程序电商平台,为了更好保证产品质量,因此提出了需要进行接口测试。 从接口本身来讲,对其测试与其他项目应该是一样的。所以不难理解,我们要对小程序的接口测试需要准备的 材料有: ...
  • 微信小程序性能测试-Trace工具

    千次阅读 2020-05-18 11:57:01
    微信小程序开发工具中提供了trace panel工具,利用trace工具可时时监控小程序的性能。分析trace文件可获取内存、CPU、fps、启动时间、各函数的执行时间等。 二、环境搭建 1、电脑上安装adb 2、安装node.js 3、...
  • 针对微信小程序的渗透测试

    千次阅读 2020-10-18 00:12:35
    Burp用于代理该端口 步骤2:打开微信-->随便点击一个小程序进入小程序主界面,然后打开文件管理器 在/data/data/com.tencent.mm/MicroMsg/xxxxxxx(不同微信文件夹也不同)/appbrand/pkg/目录下存放着刚才访问这个...
  • 使用JMeter进行高并发测试

    万次阅读 2018-12-23 20:35:06
    软件的压力测试是一种保证软件质量的行为.在金融,电商等领域应用比较普遍.通俗的讲,压力测试即在一定的硬性条件下,模拟大批量用户对软件系统进行高负荷测试.需要注意的是,压力测试的目的不是为了让软件变得完美无瑕,...
  • 并发测试工具(ubuntu 16.04)

    千次阅读 2018-11-01 19:44:46
    一、Postman 主要测试HTTP 请求,有良好的图形化界面工具 技巧:点击右上角设计符号 -&gt;...如何测试并发: 在左侧新建一个Collections ,将一个要测试的请求save 到这个Collections中 ...
  • 该程序是为自己项目写的一个测试性能的小程序。 主要通过对服务器下载文件的并发响应进行统计。 使用多线程对服务器提供的链接地址下载文件, 能统计出并发情况下的下载速度,请不要开辟开多线程,以免导致服务器受...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 220,216
精华内容 88,086
关键字:

小程序并发测试