1、并发测试的几种简单方法


本文介绍几种简单的并发测试方法。
本文分为五部分,即ab、postman、jmeter、代码模拟、testng。

一、AB

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

二、postman

1、添加 Collection

可以改名称
在这里插入图片描述

2、添加要测试的URL

在这里插入图片描述
添加请求的测试相关信息,并设置测试通过的判断条件,本示例仅仅以返回状态200为标准。设置完成后要点击保存。
在这里插入图片描述
多添加几个请求或只添加一个请求,都可以。添加完成后进行测试。

3、选中添加的Collection,设置运行时参数

在这里插入图片描述
在这里插入图片描述

4、结果如下

在这里插入图片描述

三、JMeter

Meter也是一款性能测试工具,是图形化的。
http://jmeter.apache.org/
功能比较多,详细参考官方网站

四、代码模拟

CountDownLatch是一个计数器闭锁,通过它可以完成类似于阻塞当前线程的功能,即:一个线程或多个线程一直等待,直到其他线程执行的操作完成。
CountDownLatch用一个给定的计数器来初始化,该计数器的操作是原子操作,即同时只能有一个线程去操作该计数器。调用该类await方法的线程会一直处于阻塞状态,直到其他线程调用countDown方法使当前计数器的值变为零,每次调用countDown计数器的值减1。当计数器值减至零时,所有因调用await()方法而处于等待状态的线程就会继续往下执行。这种现象只会出现一次,因为计数器不能被重置。
下图和它的方法可以体现出来:
在这里插入图片描述

// CountDownLatch类只提供了一个构造器
//参数count为计数值
public CountDownLatch(int count) {  };   
//下面这3个方法是CountDownLatch类中最重要的方法(上图能够反映出来)
//调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
public void await() throws InterruptedException { };    
//和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行
public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };   
//将count值减1
public void countDown() { };  

还需要看一个类Semaphore
Semaphore与CountDownLatch相似,不同的地方在于Semaphore的值被获取到后是可以释放的,并不像CountDownLatch那样一直减到底。
它也被更多地用来限制流量,类似阀门的 功能。如果限定某些资源最多有N个线程可以访问,那么超过N个主不允许再有线程来访问,同时当现有线程结束后,就会释放,然后允许新的线程进来。有点类似于锁的lock与 unlock过程。相对来说他也有两个主要的方法:

  • 用于获取权限的acquire(),其底层实现与CountDownLatch.countdown()类似;
  • 用于释放权限的release(),其底层实现与acquire()是一个互逆的过程。
    通过这两个类可以进行并发的模拟:
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.*;

@Slf4j
public class CuncurrencyTest {
	// 请求总数
	public static int clientTotal = 5000;
	// 同时并发执行的线程总数
	public static int threadTotal = 200;
	public static int count = 0;

	public static void main(String[] args) throws InterruptedException {
		// 定义线程池
		ExecutorService executorService = Executors.newCachedThreadPool();
		// 定义信号量 最大的线程数量
		final Semaphore semaphore = new Semaphore(threadTotal);
		final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);

		for (int i = 0; i < clientTotal; i++) {
			executorService.execute(() -> {
				try {
					semaphore.acquire();
					add();
					semaphore.release();
				} catch (InterruptedException e) {
					e.printStackTrace();
					log.error("exception", e);
				}
				countDownLatch.countDown();
			});
		}
		countDownLatch.await();
		executorService.shutdown();
		log.info("count:{}", count);

	}

	private static void add() {
		count++;
	}
}

五、Testng 并发测试

1、注解方式

@Test注解上可通过配置threadPoolSize来实现并发,threadPoolSize和invocationCount是结合使用的,当invocationCount=1的时候,threadPoolSize没有意义。invocationCount表示方法被调用的次数,如果不配置threadPoolSize,该方法会被顺序执行5次,如果配置threaPoolSize=4,下图所示的方法会一次以4个线程并发执行,缩短执行时间。
下面的例子是输出进程ID,threadPoolSize用来指明线程池的大小,也就是并发的线程数目是多少。5次调用,有3个线程可调用。

@Test(invocationCount = 50, threadPoolSize = 3)
public void test() {
	System.out.println(1);
	System.out.printf("Thrad Id : %s%n", Thread.currentThread().getId());
}

2、配置文件方式

TestNG可以以多线程的模式运行所有的test,这样可以获得最大的运行速度,最大限度的节约执行时间。当然,并发运行也是有代价的,就是需要我们的代码是线程安全的。
并发运行测试的话,需要我们指定运行的配置文件,一个示例如下:

<suite name="My suite" parallel="methods" thread-count="4">
#说明:在当前测试规划的执行过程中,为每个测试方法的执行使用单独的线程,最多并发4个线程。

<suite name="My suite" parallel="tests" thread-count="4">
# 说明:在当前测试规划的执行过程中,为每个测试用例的执行使用单独的线程(该测试用例中的测试方法共享一个线程),最多并发4个线程。

<suite name="My suite" parallel="classes" thread-count="4">
# 说明:在当前测试规划的执行过程中,为每个测试类的执行使用单独的线程(该测试类中的测试方法共享一个线程),最多并发4个线程。
<suite name="My suite" parallel="instances" thread-count="4">
# 说明:在当前测试规划的执行过程中,为每个测试类实例的执行始终使用唯一的线程(该测试实例中的测试方法共享一个线程),最多并发4个线程。
#注意:这里的parallel默认值为"none"。曾经的"true", "false"已经过时了,不建议使用。
#1.Parallel=”methods”的意思是指TestNG会将method作为并发的元子单位,即每个method运行在自己的thread中。如果parallel=”tests”,则指会将test 作为并发的元子单位
#2.Thread-count=”2”是指,运行的时候,并发度为2,同时会有两个线程在运行。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">

<suite name="Suite" parallel="methods" thread-count="2">

    <test verbose="1" preserve-order="true" name="Test1">

        <classes>
            <!-- 可以多个 -->
            <class name="org.eureka.client.userservice.test.Test1" />
        </classes>
    </test>

</suite>

public class Test1 {
	@Test(groups = { "testng-cuncurrency" })
	public void aThreadPool() {
		System.out.println("#ThreadA: " + Thread.currentThread().getId());
	}

	@Test(groups = { "testng-cuncurrency" })
	public void bThreadPool() {
		System.out.println("#ThreadB: " + Thread.currentThread().getId());
	}

	@Test(groups = { "testng-cuncurrency" })
	public void cThreadPool() {
		System.out.println("#ThreadC: " + Thread.currentThread().getId());
	}
}

测试结果
在这里插入图片描述
按照上述配置修改查看结果即可。

以上,极其简单的介绍了并发测试的几种方法,本专栏主要是介绍spring cloud及其相关组件的。

posted @ 2023-05-01 18:08  一瓢一瓢的饮  阅读(666)  评论(0)    收藏  举报  来源