最近在学响应式编程的时候,突然让我想到,新的编程范式就一定会比传统的编程范式好吗?响应式编程的性能提升在哪个方面的呢?
文章以下内容翻译来源于:**Spring Benchmark – Web MVC vs Webflux**
作者粗略的比较了传统的Spring MVC和WebFlux的性能特点,因为比较的内容只是一个简单的hello world接口,而现实生活中的业务请求复杂度会高很多。
原文博客时间在2022年8月,还是比较有参考价值的。
在Java的世界中,每个处理过程从设计上来说都是一个基于CPU线程的概念,通过阻塞操作和命令式代码来实现。因此,最初的Java Web服务器采用了每个请求一个线程的方式,遵循Servlet规范。然而,基于线程的编程方式存在一些限制,因为CPU一次只能处理有限数量的线程,大约在一万个左右。
在当今的商业环境中,某些与互联网相连的业务应用需要支持百万级的吞吐量,这已经成为一个关键需求。如果我们继续采用每个请求一个线程的方式,CPU就需要活跃地运行大量线程来处理请求。但是云主机通常提供1-2个CPU,甚至只有不到1个CPU的资源。因此,出现了基于异步事件循环、非阻塞的Web服务器,以较少的线程处理并发,并且能够在较少的硬件资源下进行扩展。
我一直想尝试使用异步Web服务器构建Java Web服务应用,但直到现在仍然没有机会,因为在我的工作场所,我们并没有处理那么高的流量。
因此,我进行了一个快速尝试,比较了基于每个请求一个线程的引擎和基于异步Web服务器的性能差异。我使用了Spring Web MVC和Spring WebFlux进行简单快速的比较。Spring Web MVC基于Servlet Web服务器,而WebFlux基于异步的Netty。
以下是我用于运行比较的框架版本、库和工具:
我在一台装有英特尔第12代 Core i7 处理器(20个CPU线程)的机器上运行了测试。
首先,创建一个父项目来存放通用库的版本。
<project ....>
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>web</module>
<module>webflux</module>
<module>gatling</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>spring-web-vs-webflux</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>18</maven.compiler.source>
<maven.compiler.target>18</maven.compiler.target>
<java.version>18</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>