2014-01-11 60 views

回答

6

好处不是直接关于“性能增益”。这些方法的目的是在读取输入(POST)数据或写入文档时避免请求线程(处于异步模式)阻塞。

Java EE7教程中有一个示例:"17.13.1 Reading a Large HTTP POST Request Using Non-Blocking I/O"(链接已更新)。

这与Tomcat在封面下使用nio是正交的。


1-有间接的性能收益。当线程可能阻塞网络I/O时,增加吞吐量的另一种策略是增加工作线程的数量。但是这会增加内存占用(导致更多“开销”)。

+0

我开始阅读有关的servlet 3.1的信息,但如何将作业发送到后台执行,并在servlet返回inmediatly释放容器线程,正在获得的东西,在执行其线程itselft,所以资源并不清楚我将被消耗。 –

+0

异步的获得利益,如果你能避免阻塞请求线程在等待类似请求到后端服务来完成。显然,如果你正在后台线程中做实际的工作......而不是其他机器...你没有取得多大成就。我想你在考虑错误的用例。 –

+0

那么,当另一台服务器完成这项工作时,真正获得它的吗?像微服务一样?这不是一台服务器在做任何事情吗?即使这个服务器是一个多层应用程序? –

8

Tomcat的读取头(和在一个NIO非阻塞模式这样做) 但读出请求机构是一个应用程序的关注,并与阻塞IO执行 (直到说明书的Servlet 3.0要求)。同样, 写入响应是通过阻塞IO来完成的,因为这也是规范的要求 。

所有这些都随Servlet 3.1而改变。

您可能希望看到email Thread这个

下面对和代码样本是从Java EE 7 Recipies它解释了使用setWritelistner和setReadListner

要实现非阻塞I/O解决方案,新编程接口 已被添加到ServletInputStream和ServletOutputStream中,以及 作为两个事件侦听器:ReadListener和WriteListener。 ReadListener 和WriteListener接口通过在 服务器内容可以在不阻塞的情况下读取或写入时调用的回调方法以非阻塞方式进行servlet I/O处理。使用 ServletInputStream.setReadList ener(ServletInputStream,AsyncContext) 方法向ServletInputStream注册ReadListener,并使用 的I/O读取 ServletInputStream。 setWriteListener(ServletOutputStream,AsyncContext) 注册WriteListener的方法。代码 以下行演示了如何用 ServletInputStream注册ReadListener实现:

AsyncContext context = request.startAsync(); 
ServletInputStream input = request.getInputStream(); 
input.setReadListener(new ReadListenerImpl(input, context)); 
3

异步IO可以对在某些情况下的性能产生深远的影响。我的经验主要是与ASP.NET相同,但它也应该适用于此。

一个servlet具有有限数量的线程来处理请求。如果存在任何阻塞IO(网络请求,数据库查询等),则处理请求的线程在等待IO完成时处于使用状态。在高容量的情况下,这可能会导致线程池饿死并导致严重的性能下降。

使用异步IO,IO不会阻塞请求线程。相反,回调被注册并随后在IO完成时被调用。与此同时,线程返回到线程池,可以继续处理其他请求。