• 模拟并发的 4 种方式,还有谁不会??


    一、Postman

    Postman 是一个款 HTTP 请求模拟工具

    首先演示一下 Postman 最基本的使用,创建一个 Spring Boot 项目,测试的代码如下:

    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("test")
    public class TestConrtoller {
    
        @GetMapping("demo")
        public String testDemo() {
            return "result~";
        }
    }
    

    为了便于操作,一般会将

    http://127.0.0.1:8080 是经常使用的地址+端口号,可以设置为环境,点击右上角的设置图标

    选择 global

    输入信息

    以后再进行测试就能这样搞简写了

    知道基本使用之后,我们来看一下如何模拟并发测试

    填写基本信息后,创建:

    这个时候会创建出Concurrency的文件夹,我们可以把刚才测试的demo的例子放进这个文件夹下:

    这个时候就可以在Concurrency下看到这个接口测试了

    选择并发测试:

    这个时候弹出我们想要的框了

    点击 Run Concurrency

    你可以立马感觉到 CPU 在“燃烧”,因为要记录并打印日志,显示的话是一条一条来的,其实测试的速度,要比你看到的打印的日志的速度快,绿色表示正常

    二、Apache Bench(AB)

    ApacheBench 是 Apache 服务器自带的一个web压力测试工具,简称ab。

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

    使用的话,首先需要安装 Apache 服务器

    网站:传送门 http://httpd.apache.org/download.cgi

    因为我的操作系统是 windows10, 这里选择 File for Microsoft Windows

    Linux下的安装是非常简单的,这里不再演示

    选择 ApacheHaus

    进入下载页面 选择适合自己电脑的版本

    文件解压到本地文件夹下,如果不是解压在c盘,需要设置参数,注意文件路径最好都是英文,关于需要设置参数,conf->httpd.conf 使用文本编辑器打开,需要修改的有三个地方:

    运行根目录,修改成自己解压到本地的路径

    监听端口,默认监听端口是80,如果已被使用会报错需要修改,如果80端口未被使用,可不修改;如果修改了监听端口,则需要把ServerName localhost也相应改成同样的端 口号

    DocumentRoot 测试文件存放地,且该目录必须存在

    配置完成后,命令行cmd进入 D:\softUtil\Apache24\bin 目录下

    httpd.exe -k install
    

    启动:

    httpd.exe -k start
    

    测试:

    -n :请求数
    -c: 并发数

    三、并发模拟工具JMeter

    JMeter也是一款性能测试工具,是图形化的。下载地址:传送门 http://jmeter.apache.org/

    需要 Java8+ 的环境

    解压到你觉得合适的目录下(注意最好是英文路径),进入它的 bin 目录下 启动 jmeter.bat 即可。

    使用很简单,首先在测试计划部分新建一个线程组

    设置好基础信息后添加HTTP请求(基本信息设置好没有OK哈,直接添加HTTP请求)

    填写HTTP请求相关的内容

    之后还要添加监听器,这里选择是图形结果

    再添加一个查看结果树吧

    在运行之前打开log Viewer

    下面开始运行:

    执行成功,来感受一下结果:

    点进去

    查看结果树

    四、代码模拟

    这里需要用到一个类,就是 CountDownLatch。CountDownLatch 是一个计数器闭锁,通过它可以完成类似于阻塞当前线程的功能,即:一个线程或多个线程一直等待,直到其他线程执行的操作完成。

    更多多线程教程可以参考:https://www.javastack.cn/categories/Java/

    CountDownLatch 用一个给定的计数器来初始化,该计数器的操作是原子操作,即同时只能有一个线程去操作该计数器。调用该类await方法的线程会一直处于阻塞状态,直到其他线程调用 countDown 方法使当前计数器的值变为零,每次调用 countDown 计数器的值减1。

    当计数器值减至零时,所有因调用await()方法而处于等待状态的线程就会继续往下执行。这种现象只会出现一次,因为计数器不能被重置。下图和它的方法可以体现出来:

    CountDownLatch类只提供了一个构造器:

    public CountDownLatch(int count) { };
    

    然后下面这 3 个方法是 CountDownLatch 类中最重要的方法(上图能够反映出来)

    public void await() throws InterruptedException { };
    public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };
    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++;
        }
    }
    

    因为 count 不是线程安全的,且没有作防护措施,结果是错的

    上面是对代码的并发模拟的简单形式,值得注意的是,这里提到的两个类不是专门做并发模拟,它们的用途很广泛,等之后更新Java网络编程的东西的时候,还会详细介绍它们。

    版权声明:本文为CSDN博主「沉晓」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/qq_42322103/article/details/102736170

    近期热文推荐:

    1.1,000+ 道 Java面试题及答案整理(2022最新版)

    2.劲爆!Java 协程要来了。。。

    3.Spring Boot 2.x 教程,太全了!

    4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!

    5.《Java开发手册(嵩山版)》最新发布,速速下载!

    觉得不错,别忘了随手点赞+转发哦!

  • 相关阅读:
    包的使用,json&pickle模块,hashlib模块
    在阿里云购买云服务器并安装宝塔面板
    python 采集斗图啦(多线程)
    python 采集斗图啦xpath
    python 采集唯美girl
    小程序接入内容内容审查接口(图片.文字)
    PEP8规范
    接口的安全问题
    学习redis知识的过程
    Spring葵花宝典
  • 原文地址:https://www.cnblogs.com/javastack/p/16341895.html
Copyright © 2020-2023  润新知