大家所熟悉的性能测试工具有Loadrunner、JMeter,以及其他小众一些的工具,如Locust、Ngrinder、Gatling等等,那么你们知道这些工具有什么不同吗?为什么有的工具能模拟数千上几万的并发,有的工具单机只能模拟一两千的并发,这其中的原因是什么呢?那么这节课我就来告诉大家,你所不了解性能测试工具的一面:并发模式。
一、多进程 / 多线程并发模式
多进程:同时执行多个程序。如,运行微信,QQ,以及各种浏览器(进程列表里能看到多个程序在运行)。 多线程:同一时刻执行多个线程。如,用浏览器一边看新闻,一边听歌,一边看下载(只启一个浏览器进程,运行多线程任务)。
1、进程和线程切换模式
支持进程和线程双模式的代表工具是Loadrunner
对于Loadrunner按线程运行VUSER和按进程运行VUSER的区别:
(1)按线程运行VUSER,LR默认情况下,每50个用户开启一个进程mmdrv.exe;controller场景运行结束,进程mmdrv.exe也会相应结束;
在Runtime setting中设置为按线程运行VUSER,设置Controller中的虚拟用户数小于等于50的话,打开windows资源管理器可以看到有一个进程mmdrv.exe;设置Controller中的虚拟用户数在51与100之间的话,打开windows资源管理器可以看到有两个进程mmdrv.exe. (2)按进程运行VUSER,系统为每1个用户开启一个进程mmdrv.exe;controller场景运行结束,进程mmdrv.exe也会相应结束;
进程的方式由于要起大量的mmdrv.exe,就要耗费大量的资源(进程属于独占资源,不像线程是共享内存空间),同等资源下无法支持更多并发,但换来的是进程的稳定性和安全性(进程独占资源,不会像线程那样发生内存共享争用情况,所以报错率极低),压测过程中不容易出现异常。在LR中这些协议不支持多线程并发:Sybase-Dblib、Infomix、Tuxedo、and PeopleSoft-Tuxedo,原因是这些协议本身不支持线程安全(会发生共享争用)。
2、多线程并发模式
支持多线程并发模式的代表工具是JMeter
(1)重度依赖于开发语言和操作系统对多线程的支持 (2)多线程切换的时候资源消耗比较多,在同等资源的情况下,产生的有效并发数量小; (3)多线程也相对容易产生错误,比如死锁,共享数据错乱; (4)可以通过丰富的界面来减少二次开发导致上面的一些错误; (5)通过扩展开发和插件实现分布式来满足并发量的不足; (6)多线程的应用技术比较成熟,未来相当长时间,还会继续应用于很多性能测试工具。
Jmeter作为多线程并发的代表工具,肯定比多进程工具要轻量化,但是有效并发还是不足,这就需要用到分布式代理,但是一个分布式代理只能启一个进程(slave),一个进程只能运行一个作业任务(进程独占一个通信端口,进程内通过多线程实现并发),所以Jmeter并不支持分布式的多任务并发,但由于Jmeter的master(主节点)支持多进程(启多个jmeter),所以有些压测平台,比如MeterSphere就利用了这一点,通过控制多个Jmeter进行多任务的并发(多进程并行任务 多线程并发测试),而不是靠分布式代理这种单进程多线程的方式:
具体可以参考我的文章《关于MeterSphere的性能测试架构理解》
3、多进程和多线程并用模式
充分利用进程和线程并发模式的代表工具是Ngrinder
虚拟用户的换算关系: 进程数:每个server起多少进程去跑 线程数:每个进程新建的线程数量 并发量 = 代理数 x 进程数 x 线程数
nGrinder支持多重测试和动态代理分配,因此只有在执行真正的测试时,才会动态地将代理分配给测试。这使得nGrinder成为所有竞争者中唯一的解决方案。由于代理的数量相对较少,多个用户可以同时运行多个测试。可能并发测试的数量取决于自由代理的数量。
总结:多线程和多进程比起来,显然要轻量的多,并且能充分的利用多核心CPU的并发处理能力,效率要高的得,但是和进程一样,一个线程也需要从头到尾的处理请求的发送、等待和接收的过程,这个过程只要没有结束,线程资源就始终得不到释放,所以多线程需要通过切换来合理的争用CPU资源,而多线程上下文切换就会严重影响多线程的执行速度,所以单台机器的有效线程并发不足,追求更高的并发,只能通过增加代理机。
二、消息循环(EventLoop)并发模式
代表工具Locust,基于协程(微线程,相当于函数,更轻量级)而不是回调方式,只能单核CPU运行,可以通过分布式来实现多核运行。
1. EventLoop模型最大的优势是在一个线程里完成大量的并发,从而避免了多线程带来的各种问题。我们可以看到,发送消息和接收消息被独立化了,不需要由一个线程负责到底,这就避免了多线程的上下文切换问题。 2. 缺点是无法同时使用多核心处理器的多个核,从而无法充分利用硬件资源,因为一个线程就实现了多并发, 使用单核CPU就够了,这样就造成了其他CPU的闲置(一种浪费行为),这就需要通过用分布式来启动多线程 ,通过多实例运行来弥补这个问题。 3. 这种并发模型里面的并发用户数只能配置固定值,在压测的过程中无法改变;这个特性与 JMeter 和 Gatling 都不一样,因为 JMeter 和 Gatling 都是可以运行的过程中改变并发用户数量的。
三、Actor并发模式
这种并发模式比较新颖,属于旧技术新应用的并发模型,代表工具是Gatling(这款工具发布的比较晚,所以采用了这个新颖的并发技术); 随着多核时代和分布式系统的到来,共享模型(上面讲的多线程技术)已经不太适合并发编程,因此几十年前就已经出现的Actor模型又重新受到了人们的重视。MapReduce就是一种典型的Actor模式,而在语言级对Actor支持的编程语言Erlang又重新火了起来,Scala也提供了Actor,但是并不是在语言层面支持,Java也有第三方的Actor包,Go语言channel机制也是一种类Actor模型。
1. 这种模型结合了多线程并发模型和消息循环并发模型的优势,避免多线程问题又充分利用硬件资源; 2. 基于消息传递的,并且使用每个虚拟用户基于一个 Actor 就可以做到相对独立(没有锁机制),并通过消息传递进行通信,所以具有单线程里进行高并发的能力; 3. 邮箱(Mail Box)是actor之间的通信桥梁,邮箱内部通过FIFO消息队列来存储发送方消息,而接收方则从邮箱中获取消息; 4. 还可以在运行时轻松地动态增加和减少并发虚拟用户数(Actor);
由于 Actor 模型的轻量和高并发性,再加上 Scala 语言基于 JVM,所以 Gatling 的并发模型结合了 JMeter 和 Locust 的优势,其尽可能地避免了多线程存在的一些问题,并可以充分使用硬件资源:多核。其次 Actor 模型核心是基于消息传递的,它具有和消息循环模型同样在单线程里面进行高并发的能力。并且它还可以在运行时轻松地动态增加和减少并发虚拟用户数(Actor)。虽然其并发模型十分优秀,但是需要使用 Scala 语言来进行开发,使得很多测试人员望而却步,导致 Gatling 的使用量并不是很广泛。不过这不能阻止人们对这项技术的向往,可以预见的是,未来的性能压测工具,会更喜欢采用这种并发模式。
如果你对Actor还有什么疑义,就参考这篇文章《十分钟理解Actor模式》
四、流量复制回放模式
流量复制回放不属于并发模式,和并发技术也无相关,但之所以我把它放在一起说,是因为这种方式也是性能测试工具采用的一类模式,不需要制造并发,只需要将生产环境的流量复制过来并进行放大,就能模拟百万并发的效果。我们模拟并发的目的,从业务层面的角度来说,也是为了模拟大量的流量,对于互联网时代来说,流量就是生命和血液,复制和复用这种流量,比单纯的模拟并发有时候更有意义。
什么是流量复制? 我们把用户访问系统造成的数据传输定义为流量,那么在用户访问系统的过程中,我们可以把进入和流出的数据复制下来,进行保存,待后续使用,即离线模式,或者转发到一个新的服务器,立即使用,即在线模式。 什么是流量回放? 获取到复制下来的流量以后,我们按照接收的时间顺序,将它们一条一条的传输到待测试的服务中,让测试服务产生相应的响应;相当于实际用户帮助我们进行测试。 通常有以下几种回放测试的情景: (1)复制下来什么内容就回放什么内容,即全量回放; (2)复制下来的内容进行一些预设规则的过滤,或者特殊的处理后,再进行回放,即选择性回放; (3)复制下来的内容,对其进行处理从中获取必须的数据项,比如上文中提到的搜索词,即关键词回放。 TCPCOPY是比较常用,极其优秀的流量复制回放工具,但是其对组网的要求较高,以下是组网架构图:
1. Online Server(OS):上面要部署 TCPcopy,从数据链路层(pcap 接口)抓请求数据包,发包是从IP层发出去; 2. Test Server(TS):TS设置路由信息,把 被测应用的 需要被捕获的响应数据包信息路由到 AS; 3. Assistant Server(AS):这是一台独立的辅助服务器,原则上一定要用同网段的一台闲置服务器来充当辅助服务器。AS 在数据链路层截获到响应包,从中抽取出有用的信息,再返回给相应的 OS 上的 TCPcopy 进程。
除了TCPCOPY,还有一款比较流行的引流工具Gor (GoReplay),有兴趣的同学可以自己去了解一下。
关于性能测试工具的并发模式就介绍到这,这篇文章的内容由我的录播课程《性能测试核心知识解惑》当中的一小块内容整理而成,有兴趣的请到我的录播课程学习,以下是这个课程的知识结构图:
性能测试核心知识解惑: https://edu.csdn.net/course/detail/31649