本系列其他文章见:《响应式Spring的道法术器》。
前情提要:Reactor快速上手 | Spring WebFlux快速上手
本文源码
1.4 从负载测试看异步非阻塞的优势
前面总是“安利”异步非阻塞的好处,下面我们就实实在在感受一下响应式编程在高并发环境下的性能提升。异步非阻塞的优势体现在I/O操作方面,无论是文件I/O、网络I/O,还是数据库读写,都可能存在阻塞的情况。
我们的测试内容有三:
- 首先分别创建基于WebMVC和WebFlux的Web服务,来对比观察异步非阻塞能带来多大的性能提升,我们模拟一个简单的带有延迟的场景,然后启动服务使用gatling进行测试,并进行分析;
- 由于现在微服务架构应用越来越广泛,我们基于第一步的测试项目进一步观察调用存在延迟的服务的情况下的测试数据,其实主要是针对客户端的测试:阻塞的
RestTemplate
和非阻塞的WebClient
; - 针对MongoDB的同步和异步数据库驱动进行性能测试和分析。
说明:本节进行的并非是严谨的基于性能调优的需求的,针对具体业务场景的负载测试。本节测试场景简单而直接,各位朋友GET到我的点即可。
此外:由于本节主要是进行横向对比测试,因此不需要特定的硬件资源配置,不过还是建议在Linux环境下进行测试,我最初是在Win10上跑的,当用户数上来之后出现了不少请求失败的情况,下边的测试数据是在一台系统为Deepin Linux(Debian系)的笔记本上跑出来的。
那么我们就开始搭建这套简单粗暴的测试环境吧~
1.4.1 带有延迟的负载测试分析
1)搭建待测试项目
我们分别基于WebMVC和WebFlux创建两个项目:mvc-with-latency
和WebFlux-with-latency
。
为了模拟阻塞,我们分别在两个项目中各创建一个带有延迟的/hello/{latency}
的API。比如/hello/100
的响应会延迟100ms。
mvc-with-latency
中创建HelloController.java
:
@RestController
public class HelloController {
@GetMapping("/hello/{latency}")
public String hello(@PathVariable long latency) {
try {
TimeUnit.MILLISECONDS.sleep(latency); // 1
} catch (InterruptedException e) {
return "Error during thread sleep";
}
return "Welcome to reactive world ~";
}
}
- 利用sleep来模拟业务场景中发生阻塞的情况。
WebFlux-with-latency
中创建HelloController.java
:
@RestController
public class HelloController