zoukankan      html  css  js  c++  java
  • 同时处理多请求

    在工作中遇到同时向多个服务请求的场景,在此将自己的研究过程记录一下

    模拟三个请求requestA、requestB、requestC:

    @Service
    public class ParallelService {
    
        public String requestA() {
            try {
                TimeUnit.MILLISECONDS.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "A";
        }
    
        public String requestB() {
            try {
                TimeUnit.MILLISECONDS.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "B";
        }
    
        public String requestC() {
            try {
                TimeUnit.MILLISECONDS.sleep(2500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "C";
        }
    
    }

    建立一个测试类ParallelController,request方法用来模拟请求不同服务:

    @Slf4j
    @RestController @RequestMapping(
    "parallel") public class ParallelController { @Autowired private ParallelService parallelService; private String request(int index) { if (index == 0) { return parallelService.requestA(); } if (index == 1) { return parallelService.requestB(); } if (index == 2) { return parallelService.requestC(); } return null; } }

    接下来,就开始尝试不同的请求方式:

    串行(传统方式)

       /**
         * 串行(传统请求)
         */
        @GetMapping("/test1")
        public void test1() {
            long start = System.currentTimeMillis();
            List<String> list = new ArrayList<>();
            IntStream.range(0, 3).forEach(index -> {
                list.add(request(index));
            });
            log.info("串行,响应结果:{},响应时长:{}", Arrays.toString(list.toArray()), System.currentTimeMillis() - start);
        }

    使用JMeter进行压测,压测参数如下:

    创建30个线程,在20秒之内循环请求,结果:

    从控制台结果可以看到:请求是顺序执行,所以结果都是[A, B, C],响应时长也很稳定

    从JMeter结果可以看到:平均响应时长:5805ms,最小响应时长:5507ms,最大响应时长:6497ms,TPS:5.0/sec

    并行

    并行采用的是java8的语法流,利用多核处理器同时去请求,当获取所有请求结果后才终止

       /**
         * 并行请求
         */
        @GetMapping("/test2")
        public void test2() {
            long start = System.currentTimeMillis();
            List<String> list = new ArrayList<>();
            IntStream.range(0, 3).parallel().forEach(index -> {
                list.add(request(index));
            });
            log.info("java8并行,响应结果:{},响应时长:{}", Arrays.toString(list.toArray()), System.currentTimeMillis() - start);
        }

    使用jmeter同样的参数压测,结果:

    从控制台结果可以看到:请求是独立执行没有顺序,所以结果是不确定的,响应时长很不稳定

    从JMeter结果可以看到:平均响应时长:16648ms,最小响应时长:2513ms,最大响应时长:36052ms,TPS:1.3/sec

     多线程

     多线程的处理方式是,创建多个线程,分别去请求,当获取所有请求结果后才终止

       /**
         * 多线程请求
         */
        @GetMapping("/test3")
        public void test3() {
            long start = System.currentTimeMillis();
    
            List<String> list = new ArrayList<>();
            List<Future<String>> futureList = new ArrayList<>();
            ExecutorService executor = Executors.newFixedThreadPool(3); // 开启3个线程
            IntStream.range(0, 3).forEach(index -> {
                Future<String> task = executor.submit(() -> request(index));
                futureList.add(task);
            });
            for (Future<String> future : futureList) {
                try {
                    // 如果任务执行完成,future.get()方法会返回Callable任务的执行结果。
                    // future.get()方法会产生阻塞,所有线程都阻塞在这里,当获取到一个结果后,才执行下一个
                    list.add(future.get());
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                }
            }
            // 停止接收新任务,原来的任务继续执行
            executor.shutdown();
    
            log.info("多线程,响应结果:{},响应时长:{}", Arrays.toString(list.toArray()), System.currentTimeMillis() - start);
        }

    从控制台结果可以看到:请求是顺序执行的,结果都是[A, B, C],响应时长比较稳定

    从JMeter结果可以看到:平均响应时长:2505ms,最小响应时长:2503ms,最大响应时长:2519,TPS:11.4/sec

    结论:

    1、串行处理多请求,代码很简单,响应时长是每个请求时长的总和,很稳定但是效率不高

    2、使用java8并行处理,代码很简单,响应时长很不稳定,效率也不高,不建议使用

    3、使用多线程处理时,代码复杂,响应时长为单个请求中时长最长的那个,效率很高,推荐使用

  • 相关阅读:
    web端限时活动逻辑处理总结
    js 的一些知识 摘自http://img0.pconline.com.cn/Pc_intranet/1105/13/313647_7.pdf
    HTML实现简单计算器
    HTML打折计算价格
    实现多线程的同时复制(三个线程同时复制)
    利用多线程实现并发调用,实现一个存钱多人取钱函数
    用字符流实现每个文件夹中创建包含所有文件信息的readme.txt
    Java实现文件在某个目录的检索
    Java实现列出目录下所有文件和文件夹
    大华、海康、宇视、华为等厂家RTSP标准拉流地址
  • 原文地址:https://www.cnblogs.com/xuwenjin/p/11280357.html
Copyright © 2011-2022 走看看