51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 855|回复: 0
打印 上一主题 下一主题

[原创] Junit单元测试多线程并发性能

[复制链接]
  • TA的每日心情
    无聊
    昨天 09:19
  • 签到天数: 933 天

    连续签到: 5 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2022-12-7 14:51:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    1.开发中遇到的实际问题
      开发一个业务接口功能的过程中,由于没有充分考虑到前端的并发调用,导致接口数据有误。对于这样一个问题,首先要定位问题出现的原因,根据网关调用的日志链路排查。接口主要是在reids中存入对应数据,也redis写数据进行了幂等。但是没充分考虑到线上的连续调用,测试也没有对接口进行并发测试。
      确定可能是因为并发导致的接口返回数据问题,因此先对接口进行并发测试,复现并发调用出现的问题,并且提供解决方案。
      2.利用[url=]单元测试[/url]来测试多线程
      ·遇到的问题
      当在单元测试中启动多个线程,但是多个线程启动或者执行比较耗时的情况下,Test线程结束后,会直接结束所有的线程,创建的多个线程不会去执行。
      ·解决方案
      最简单的方法就是让主线程阻塞,等待其他子线程执行完毕之后继续,比如可以让主线程睡眠几秒钟。
      TimeUnit.SECONDS.sleep(10);

      或者使用join方法,join() 的作用:让“主线程”等待“子线程”结束之后才能继续运行。
      类似:
      Thread threadA = new Thread(connectionThread);
      Thread threadB = new Thread(connectionThread);
      threadA.start();
      threadB.start();
      threadA.join();
      threadB.join();


      这样多个线程可以一起执行。不过线程多了,这样写比较麻烦。
      ·多线程测试接口案例–复现线上问题
        /**
         * 测试单车评价选择接口的多线程并发
         */
        @Test
        public void multiThreadSelectTest() throws InterruptedException {
          OrderRateSettingsSelectReqDTO reqDTO =  new OrderRateSettingsSelectReqDTO();
          reqDTO.setOrderType(BizTypeEnum.BIKE.getValue());
          reqDTO.setOrderGuid("16683970396451200496215");
          for(int i=0;i<2;i++){
            new Thread( () -> {
              System.out.println(Thread.currentThread().getName());
              Result<OrderRateSettingsSelectResDTO> result =  bikeRateService.bikeOrderRateSettingsSelect(reqDTO);
              System.out.println(JSON.toJSONString(result));
            }).start();
          }
          TimeUnit.SECONDS.sleep(10);
        }


      上面单测案例运行之后打印输出结果:
      Thread-34
      Thread-33
      {"code":0,"data":{"carrierId":"16683970396451200496215","needRate":true,"rateToken":"78f1828b-600e-4392-a708-9cf9b0811894","settingsId":"151889654407250000","userNewId":1200496215},"msg":"ok","success":true}
      {"code":0,"data":{"carrierId":"16683970396451200496215","needRate":true,"rateToken":"828b-600e-4392-a708-9cf9b0811894","settingsId":"151889654407250000","userNewId":1200496215},"msg":"ok","success":true}


      上述结果表明,接口多线程并发的返回结果token结果不一致,没有达到接口的幂等需要。底层redis并发调用导致创建的token被覆盖。最简单的解决方案是家并发锁,并发调用的时候只有一个线程可以执行接口,从而有效的解决了这个线上问题。

    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-4-20 04:10 , Processed in 0.059939 second(s), 23 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表