Spring MVC(异步)与 Spring WebFlux
Posted
技术标签:
【中文标题】Spring MVC(异步)与 Spring WebFlux【英文标题】:Spring MVC (async) vs Spring WebFlux 【发布时间】:2018-03-18 06:57:42 【问题描述】:我正在尝试了解 Spring WebFlux。到目前为止,我发现的核心是响应式的,没有 Servlet API,每个请求没有线程,HTTP 2,服务器推送,应用程序/流 + json。
但是 Spring MVC 中的异步调用有什么区别呢?我的意思是在 Spring MVC 中,当您返回 Future、DefferedResult 等时,您会在单独的线程中执行的请求处理程序(控制器方法)中获得逻辑,因此您也可以从节省线程池资源以调度请求中受益。
那么您能否强调一下与此相关的差异?为什么 WebFlux 在这里更好?
非常感谢您的宝贵时间!
【问题讨论】:
响应式编程是推送驱动的,使用单个调度程序线程(效率很高),而旧模型仍然受限于线程池中的线程数。 @M. Deinum 但在这种情况下,我受限于一个线程可以处理的负载。为什么不使用其中的几个,而不仅仅是一个具有多核系统的? 它是一个事件调度线程,它是一个完全不同的模型。它只调度事件(非常快),而另一个模型仍然阻塞。 @M. Deinum 好的,这很有趣,我确定我应该看看它,谢谢! @M. Deinum,请分享请求生命周期 【参考方案1】:Servlet API 阻塞 I/O,每个 HTTP 请求需要 1 个线程。 Spring MVC 异步依赖于 Servlet API,它只提供容器线程和请求处理线程之间的异步行为,而不是端到端。
另一方面,Spring WebFlux 通过使用 HTTP 套接字并通过套接字一次推送数据块,通过固定数量的线程实现并发。这种机制被称为事件循环,这是一个由Node.js 流行起来的想法。这种方法具有可扩展性和弹性。 Spring 5 的 spring-webflux 使用 事件循环 方法来提供异步行为。
更多内容可以阅读
Servlet vs. Reactive Spring Boot performance battle Comparing WebFlux with Spring Web MVC【讨论】:
【参考方案2】:Servlet 异步模型在容器线程(1 个 Servlet 请求/线程模型)和应用程序中的请求处理之间引入了异步边界。处理可以发生在不同的线程上或等待。最后,您必须分派回容器线程并以阻塞方式读取/写入(InputStream
和 OutputStream
本质上是阻塞 API)。
使用该模型,您需要许多线程来实现并发(因为其中许多线程可能会被阻塞以等待 I/O)。这会消耗资源,并且可能需要权衡取舍,具体取决于您的用例。
使用非阻塞代码,您只需要几个线程即可同时处理大量请求。这是一个不同的并发模型;与任何模型一样,它也有好处和权衡。
有关该比较的更多信息,此Servlet vs. Reactive stacks talk 应该很有趣。
【讨论】:
据我了解,另一个好处是响应本身的内容。 Publisher(Flux/Mono)被认为比 Future 更“先进”,因为它可以更好地控制流量,例如背压等。 你能详细说明一下吗?即使对于响应式 webFlux,我们也必须等待写入套接字。据我了解,在 Asyc servlet api 容器线程的情况下,必须将请求传递到应用程序 threadPool 以等待空闲工作线程,并且在传递线程后变为空闲状态,并且可以在传递该请求后将其重用于另一个请求。为什么说用那个模型,需要很多线程才能实现并发? @g*** 我们有时需要等待以非阻塞方式写入/读取套接字,在这种情况下,在此期间没有线程处于空闲状态。使用 Servlet 3.0 模型,服务器线程数与最大并发请求数成正比。请观看我指出的谈话,这一切都在那里进行了详细的解释。 对不起,我不清楚。在 DeferedResult 的情况下,Tomcat 线程只是将请求传递给应用程序 threadPool - 它的操作非常短,因此它已准备好处理另一个请求。 webFlux 提供了哪些杀手级功能? 根据您的回答,我了解您对 DeferedResult 的关注包含在该短语中:最后,您必须分派回容器线程并以阻塞方式读/写(InputStream和 OutputStream 本质上是阻塞 API)。 你想说 WebFlux 有一些可以异步读/写的神奇套接字吗?有可能吗?以上是关于Spring MVC(异步)与 Spring WebFlux的主要内容,如果未能解决你的问题,请参考以下文章
传统的Spring Web MVC如何像WebFlux一样异步处理请求?