反应式编程是否比非反应式编程消耗更多资源?弹簧

时间:2017-07-11 09:54:24

标签: java spring-boot spring-io

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

该服务有两种变体:

  1. 使用Spring Boot,MongoRepository的非反应式实现。此服务将数据作为List
  2. 返回
  3. Spring Boot,ReactiveMongoRepository,spring-boot-starter-webflux的反应式实现。此服务将数据作为Flux返回。
  4. 在两个实现中,REST控制器直接从存储库中提取数据并将其作为List resp返回。作为Flux。没有执行进一步的应用程序逻辑。

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

    事实上,不仅非反应性实现具有更好的HTTP吞吐量,而且可能更有趣的是,它比响应式实现消耗更少的CPU和更少的线程! 这与预期特别相反,因为我们预计反应型版本会按照https://spring.io/blog/2016/07/28/reactive-programming-with-spring-5-0-m1

    中提到的少量线程进行扩展。

    我们需要在设置中进行调整吗?

    有人遇到类似问题吗?

3 个答案:

答案 0 :(得分:1)

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

我们对这两个服务器的10000个请求进行了基准测试,并发率为100 req / sec。结果并不令人惊讶:-

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利用率并没有限制可扩展性。

如果非活动堆栈不受线程上下文切换和线程创建的限制,则可扩展更多。

答案 1 :(得分:0)

http://blog.ippon.tech/spring-5-webflux-performance-tests/

我建议你阅读这篇文章。在反应弹簧中有测试结果。

答案 2 :(得分:0)

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