本文来源:https://blog.csdn.net/get_set/article/details/
作者:享学IT
本文已收录至我的GitHub
前面总是“安利”异步非阻塞的好处,下面我们就实实在在感受一下响应式编程在高并发环境下的性能提升。异步非阻塞的优势体现在I/O操作方面,无论是文件I/O、网络I/O,还是数据库读写,都可能存在阻塞的情况。
我们的测试内容有三:
说明:本节进行的并非是严谨的基于性能调优的需求的,针对具体业务场景的负载测试。本节测试场景简单而直接,各位朋友GET到我的点即可。 此外:由于本节主要是进行横向对比测试,因此不需要特定的硬件资源配置,不过还是建议在Linux环境下进行测试,我最初是在Win10上跑的,当用户数上来之后出现了不少请求失败的情况,下边的测试数据是在一台系统为Deepin Linux(Debian系)的笔记本上跑出来的。
那么我们就开始搭建测试环境吧~ (关于Spring WebFlux 不熟悉的话,请参考Spring WebFlux快速上手)。
1.4.1 带有延迟的负载测试分析
1)搭建待测试项目
我们分别基于WebMVC和WebFlux创建两个项目:和。
为了模拟阻塞,我们分别在两个项目中各创建一个带有延迟的的API。比如的响应会延迟100ms。
中创建:
中创建:
然后各自在中配置端口号8091和8092:
启动应用。
2)编写负载测试脚本
本节我们采用gatling来进行测试。创建测试项目。
POM中添加gatling依赖和插件(目前gradle暂时还没有这个插件,所以只能是maven项目):
在下创建测试类,gatling使用scala语言编写测试类:
如上,这个测试的场景是:
其中URL和用户量通过、、变量传入,借助maven插件,通过如下命令启动测试:
就表示用户量为300的对的测试。
3)观察线程数量
测试之前,我们打开jconsole观察应用(连接MVCWithLatencyApplication)的线程变化情况:
(6)Spring WebFlux性能测试——响应式Spring的道法术器
如图(分辨率问题显示不太好)是刚启动无任何请求进来的时候,默认执行线程有10个,总的线程数31-33个。
比如,当进行用户数为2500个的测试时,执行线程增加到了200个,总的线程数峰值为223个,就是增加的这190个执行线程。如下:
(6)Spring WebFlux性能测试——响应式Spring的道法术器
由于在负载过去之后,执行线程数量会随机减少回10个,因此看最大线程编号估算线程个数的话并不靠谱,我们可以用“峰值线程数-23”得到测试过程中的执行线程个数。
4)负载测试
首先我们测试:
测试数据如下(Tomcat最大线程数200,延迟100ms):
(6)Spring WebFlux性能测试——响应式Spring的道法术器
(6)Spring WebFlux性能测试——响应式Spring的道法术器
由以上数据可知:
这里我们不难得出原因,那就是当所有可用线程都在阻塞状态的话,后续再进入的请求只能排队,从而当达到最大线程数之后,响应时长开始上升。我们以6000用户的报告为例:
title
这幅图是请求响应时长随时间变化的图,可以看到大致可以分为五个段:
所有请求的响应时长分布如下图所示:
title
A/E段与C段的时长只差就是平均的排队等待时间。在持续的高并发情况下,大部分请求是处在C段的。而且等待时长随请求量的提高而线性增长。
增加Servlet容器处理请求的线程数量可以缓解这一问题,就像上边把最大线程数量从默认的200增加的400。
最高200的线程数是Tomcat的默认设置,我们将其设置为400再次测试。在中增加:
测试数据如下:
(6)Spring WebFlux性能测试——响应式Spring的道法术器
(6)Spring WebFlux性能测试——响应式Spring的道法术器
由于工作线程数扩大一倍,因此请求排队的情况缓解一半,具体可以对比一下数据:
这也再次印证了我们上边的分析。增加线程数确实可以一定程度下提高吞吐量,降低因阻塞造成的响应延时,但此时我们需要权衡一些因素:
我们再来看一下对于的测试数据:
(6)Spring WebFlux性能测试——响应式Spring的道法术器
可见,非阻塞的处理方式规避了线程排队等待的情况,从而可以用少量而固定的线程处理应对大量请求的处理。
除此之外,我又一步到位直接测试了一下20000用户的情况:
最后,再给出两个吞吐量和响应时长的图,更加直观地感受异步非阻塞的WebFlux是如何一骑绝尘的吧:
(6)Spring WebFlux性能测试——响应式Spring的道法术器
(6)Spring WebFlux性能测试——响应式Spring的道法术器
综上来说,结论就是相对于Servlet多线程的处理方式来说,Spring WebFlux在应对高并发的请求时,借助于异步IO,能够以少量而稳定的线程处理更高吞吐量的请求,尤其是当请求处理过程如果因为业务复杂或IO阻塞等导致处理时长较长时,对比更加显著。
本文模拟的延迟时间较长,达到了100ms,虽然有些夸张,但是不能否认IO阻塞的严重性。如果CPU执行一条指令的时间是1秒,那么内存寻址就需要4分20秒,SSD寻址需要4.5天,磁盘寻址需要1个月。异步IO能够将CPU从“漫长”的等待中解放出来,不再需要堆砌大量的线程来提高CPU利用率。这也是Spring WebFlux能够以少量线程处理更高吞吐量的原因。
此时,我们更加理解了Nodejs的骄傲,不过我们大Java语言也有了Vert.x和现在的Spring WebFlux。
到此这篇webflux与springmvc(webflux与springmvc对比)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/rfx/61777.html