java - 响应式编程是否比非响应式编程消耗更多资源?

标签 java spring-boot project-reactor reactor spring-io

我们目前正面临 spring webFlux 的性能问题。 为了确定响应式(Reactive)编程的好处,我们实现了一个 Spring Boot 服务,该服务从 MongoDB 获取数据并通过 REST API 将其返回给消费者。

该服务有两种变体:

  1. 使用 Spring Boot 的非响应式实现,MongoRepository。此服务以列表形式返回数据
  2. 使用 Spring Boot、ReactiveMongoRepository、spring-boot-starter-webflux 的响应式(Reactive)实现。此服务将数据作为 Flux 返回。

在这两种实现中,REST Controller 直接从存储库中获取数据并将其作为列表返回。作为助焊剂。不执行进一步的应用程序逻辑。

我们对调用该服务的 100 个用户进行了一次小型负载/性能测试,我们发现非响应式实现的性能远好于响应式实现。

事实上,非响应式实现不仅具有更好的 HTTP 吞吐量,而且也许更有趣的是,它比响应式实现消耗更少的 CPU 和更少的线程! 这尤其与预期背道而驰,因为我们预计响应式(Reactive)版本会使用少量线程进行扩展,如 https://spring.io/blog/2016/07/28/reactive-programming-with-spring-5-0-m1 中所述。

我们需要在设置中调整什么吗?

有人遇到过类似的问题吗?

最佳答案

我们使用 Spring-Data-Reactive-Cassandra 和 Spring-Webflux 针对 Spring-Data-Cassandra 和 Spring-MVC 执行了类似的测试。

我们针对 10000 个请求和 100 个请求/秒的并发性对两个服务器进行了基准测试。结果并不令人惊讶:-

Non Reactive Stack:-
         Concurrency Level:      100
         Time taken for tests:   22.945 seconds
         Complete requests:      10000
         Failed requests:        0
         Percentage of the requests served within a certain time (ms)
           50%    190
           66%    253
           75%    288
           80%    314
           90%    384
           95%    465
           98%    627
           99%    824
          100%   1208 (longest request)

Reactive Stack:-
         Concurrency Level:      100
         Time taken for tests:   30.061 seconds
         Complete requests:      10000
         Failed requests:        0
         Percentage of the requests served within a certain time (ms)
           50%    304
           66%    379
           75%    421
           80%    443
           90%    507
           95%    589
           98%    694
           99%    736
          100%    858 (longest request)

While performing these tests, the non-reactive stack spawned 147 threads, while the reactive stack spawned 48 threads.

如果比较结果,非响应式(Reactive)堆栈比响应式(Reactive)堆栈稍微快一些。它在大约 23 秒内将 10,000 个对象持久化到数据库中,而响应式(Reactive)堆栈大约需要 30 秒。但是,如果您比较两个堆栈中最慢的 2% 请求, react 堆栈快了近 28%。

具有较少线程数的响应式(Reactive)堆栈具有更均匀分布的响应时间。没有一个请求被搁置。而对于非响应式(Reactive)堆栈,1% 的请求相对来说非常慢。

在持续一段时间内增加调用次数后,与非响应式(Reactive)堆栈相比,响应式(Reactive)堆栈将能够更好地扩展。由于与可以在服务器上打开的套接字数相比,您可以在服务器上生成的线程数要少得多。此外,在这些测试期间,两种情况下的 CPU 利用率均低于 33%,从而证明 CPU 利用率并未限制可扩展性。

如果非 react 性堆栈不受线程上下文切换和线程创建的限制,它可以扩展得更多。

关于java - 响应式编程是否比非响应式编程消耗更多资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45031179/

相关文章:

java - 线性和二分搜索逻辑错误

java - 存储库对象未在服务类中 Autowiring

运行maven package命令时java spring boot jar文件错误

java - 如何在 Mono 中抛出另一个异常?

java-8 - 如何将对象保存到通量内的 react 性存储库

project-reactor - Reactor 中的 Mono doOnEmpty?

java - 从依赖 jar 中找不到类

Java:向接口(interface) List<E> 添加一个新方法

java - TextView 和 ViewGroup,java.lang.RuntimeException :

java - com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException : Cannot delete or update a parent row: a foreign key constraint fails