Java - Servlet 3.0 中的异步与 Servlet 3.1 中的 NIO

标签 java servlets servlet-3.0 servlet-3.1

直到现在,因为它适用于服务 http 请求,我认为术语 - asynchronousnon-blocking i/o 意思相同。但显然,它们分别在 servlet 3.0 和 3.1 中分别实现了。我很难理解这里的区别......

有人可以更清楚地说明这个话题吗?具体来说,我正在寻找一个服务器的 servlet 3.0 实现如何异步但阻塞线程的示例?我想如果我理解了这一点,可能更容易理解 servlet 3.1 中的非阻塞 i/o 试图解决的确切问题。

最佳答案

我会尽量总结我学到的东西。要理解 Servlet 3.0 和 Servlet 3.1 解决的问题,让我们这样看:

Servlet 3.0 之前:
同步处理请求的问题在于它导致线程(执行繁重的工作)在响应消失之前运行了很长时间。如果这种情况大规模发生,servlet 容器最终会耗尽线程——长时间运行的线程会导致线程饥饿。

在 Servlet 3.0 之前,对于这些长时间运行的线程有特定于容器的解决方案,我们可以在其中生成一个单独的工作线程来完成繁重的任务,然后将响应返回给客户端。 servlet线程启动worker线程后返回servlet池。 Tomcat的Comet、WebLogic的FutureResponseServlet和WebSphere的Asynchronous Request Dispatcher都是异步处理的一些实现例子。
(有关详细信息,请参阅 link 1。)

Servlet 3.0 异步:
实际工作可以委托(delegate)给线程池实现(独立于容器特定解决方案)。 Runnable 实现将执行实际处理,并将使用 AsyncContext 将请求分派(dispatch)到另一个资源或写入响应。我们也可以在AsyncContext对象中添加AsyncListener实现来实现回调方法。
(有关详细信息,请参阅 link 1。)

Servlet 3.1 NIO:
如上所述,Servlet 3.0 允许异步请求处理,但只允许传统 I/O(与 NIO 相对)。为什么传统 I/O 是个问题?

在传统的 I/O 中,有两种情况需要考虑:

  • 如果进入服务器 (I/O) 的数据阻塞或流式传输速度比服务器读取速度慢,则尝试读取此数据的服务器线程必须等待该数据。
  • 另一方面,如果从服务器写入ServletOutputStream的响应数据很慢,则客户端线程不得不等待。在这两种情况下,执行传统 I/O(用于请求/响应)的服务器线程都会阻塞。

换句话说,在 Servlet 3.0 中,只有请求处理部分变成了异步,而用于处理请求和响应的 I/O 则没有。如果有足够多的线程阻塞,则会导致线程饥饿并影响性能。

在 Servlet 3.1 NIO 中,这个问题通过 ReadListenerWriteListener 接口(interface)解决了。这些在 ServletInputStreamServletOutputStream 中注册。监听器具有回调方法,当内容可供读取或可写入时调用,而 servlet 容器不会阻塞 I/O 线程。因此,这些 I/O 线程被释放,现在可以服务于其他提高性能的请求。 (有关详细信息,请参阅 link 2。)

致谢

关于Java - Servlet 3.0 中的异步与 Servlet 3.1 中的 NIO,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39802643/

相关文章:

java - 请求被拒绝,因为其大小超出了配置的最大值

javascript - 如何从servlet页面中的ajax请求中获取数据?

java - WAS8 : updating web. xml 从版本 ="2.4"到版本 ="3.0"导致 OutOfMemoryException?

java - Servlet 3.0 async 支持的缺点

Java,在swing应用程序中保持全局数据库 session

java - 测试驱动开发不适合我的类(class)

java - BufferedInputStream的数量?

tomcat - 将 servlet 映射到 mydomain/myservlet/和 mydomain/myservlet/index.html

java - 服务器发送的事件不适用于 Jersey SSE

java - 通过泛型限制类型参数