【问题标题】:Does Reactive programming consumes more resources than non-reactive?反应式编程是否比非反应式编程消耗更多资源?
【发布时间】:2023-04-07 20:49:01
【问题描述】:

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

该服务有两种变体:

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

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

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

事实上,非响应式实现不仅具有更好的 HTTP 吞吐量,而且也许更有趣的是,它比响应式实现消耗的 CPU 和线程更少! 这特别出乎我们的意料,因为我们预计响应式版本可以使用https://spring.io/blog/2016/07/28/reactive-programming-with-spring-5-0-m1 中提到的少量线程进行扩展

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

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

【问题讨论】:

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


    【解决方案1】:

    让我试着解释一下这种行为的可能原因。反应式应用程序的工作速度并不比反应式应用程序快。如果请求队列不为空,则反应式应用程序不允许系统处于空闲状态。由于您在低负载下进行了测试,因此您没有看到反应式应用程序的优缺点,但您已经看到了性能降级。性能低于非活动应用程序,因为反应式执行的开销很小。

    【讨论】:

      【解决方案2】:

      我们使用 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)
      

      在执行这些测试时,非反应式堆栈产生了 147 个线程,而反应式堆栈产生了 48 个线程。

      如果您比较结果,非反应式堆栈比反应式堆栈稍快。它在大约 23 秒内将 10,000 个对象保存在数据库中,而反应堆栈大约需要 30 秒。但是,如果您比较两个堆栈中最慢的 2% 请求,则反应堆栈几乎快 28%。

      反应性堆栈,线程数较少,响应时间分布更均匀。没有任何请求被搁置。而对于非响应式堆栈,1% 的请求相对来说非常慢。

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

      如果没有线程上下文切换和线程创建的限制,非反应式堆栈可以扩展得更多。

      【讨论】:

        猜你喜欢
        • 2019-03-16
        • 1970-01-01
        • 2013-11-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-24
        • 2010-11-04
        • 2015-07-25
        相关资源
        最近更新 更多