gpt4 book ai didi

java - 可调用/可运行 Controller 方法 : What's the point?

转载 作者:搜寻专家 更新时间:2023-10-31 20:09:10 24 4
gpt4 key购买 nike

在 Spring 中,您可以让 Controller 返回一个 Callable 而不是 T,这将立即释放请求处理线程并在 WebAsyncManager 管理的 MvcAsync 线程中计算结果。您只需要将 Controller 方法内容包装在 return () -> {... return result; };。非常简单!

但这有什么意义呢?
有什么区别?a) 拥有 500 个请求处理线程并让它们完成所有工作并且
b) 只有几个请求处理线程并在 concurrencyLimit 为 500 的 Callables 中执行所有请求

第二个选项 b) 实际上对我来说看起来更糟,因为管理整个 MvcAsync 魔法涉及开销。

我知道如何收获 @Async 方法来一次执行两个方法并在两个方法完成后返回结果,但我显然不理解 Callable Controller 方法。

最佳答案

假设您有一个 Tomcat 服务器,它有 10 个线程监听客户端请求。如果您有一个客户端调用一个需要 5 秒响应的端点,那么该客户端会在这 5 秒内保持该线程。添加几个并发客户端,您很快就会在这 5 秒内耗尽线程。

情况更糟,因为在这 5 秒的大部分时间里,您的请求主要是在执行 I/O,这意味着您只是阻塞您的线程,除了等待什么都不做。

所以,Spring能够使用Callable、CompletableFuture或ListenableFuture作为 Controller 的返回类型,正是为了让程序员在一定程度上克服这种问题。

从根本上说,仅返回其中一种类型只会释放 Web 服务器线程,使其可供另一个客户端使用。因此,您可以在相同的时间内接待更多的客户,但是,这本身可能不足以实现非阻塞 IO(又名 NIO)API。

这些特性中的大部分来自 Servlet API 和 Servlet Async IO 提供的核心功能,Spring 应该在底层使用它们。您可能想看看以下有趣的视频,它们帮助我从头开始理解这一点:

这些视频解释了 Servlet Async I/O 背后的想法以及实现 NIO Web 应用程序的最终目标。

这里的 chalice 是达到这样一个点,即线程池中的线程永远不会阻塞等待某些 I/O 发生。它们要么在做一些 CPU 密集型工作,要么回到线程池中供其他客户端使用。当您执行 I/O 时,您不会引入等待,您注册某种形式的回调,用于在结果准备好时通知您,同时您可以使用您宝贵的 CPU 核心来处理其他事情。如果您仔细考虑,Callable、CompletableFuture 或 ListenableFuture 是 Spring 基础架构在后台使用的那种回调对象,用于调用它们的功能以在单独的线程中处理请求。

这会增加您的吞吐量,因为您可以同时处理更多的客户端,只需优化您宝贵的 CPU 资源的使用,特别是如果您以 NIO 方式执行此操作,因为您可以想象,只需将请求移至另一个线程,虽然有益(因为您释放了一个有值(value)的 Tomcat 线程),但仍然会阻塞,因此,您只是将问题转移到另一个线程池。

我相信这个基本原则也是 Spring 团队目前在 Project Reactor 中所做工作的很大一部分背后的原因。因为为了利用此类功能的强大功能,您需要在 API 中引入异步编程,而这很难做到。

这也是像 Netty 这样的框架激增的原因。 , RxJava , Reactive Streams InitiativeProject Reactor .他们都在寻求推广这种优化和编程模型。

还有一个有趣的新框架运动,利用这个强大的特性,并试图与 Spring 竞争甚至补充 Spring 但在该领域的功能有限。我说的是有趣的项目,例如 Vert.xRatpack现在我们开始了,这个功能是Node.js 的主要卖点之一。

关于java - 可调用/可运行 Controller 方法 : What's the point?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42076887/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com