我想知道如果像Tomcat,Jetty等servlet容器已经使用nio来读取和写入数据,是否真的需要在servlet输入和输出流上使用setWritelistner
和setReadListner
?是否有额外的性能提升?
答案 0 :(得分:8)
Tomcat读取标题(并在NIO的非阻塞模式下执行此操作) 但阅读请求主体是一个应用程序问题,并执行 阻塞IO(直到规范的Servlet 3.0要求)。同样, 写入响应是通过阻塞IO来完成的,因为它也是一个 规范的要求。
所有这些都随Servlet 3.1而改变。
您可能希望{/ 3}}看到此
下面的para和code示例来自Java EE 7 Recipies,它解释了setWritelistner和setReadListner的使用
实现非阻塞I / O解决方案,新的编程接口 已添加到ServletInputStream和ServletOutputStream中 作为两个事件侦听器:ReadListener和WriteListener。 ReadListener 和WriteListener接口使servlet I / O处理发生 通过在调用时调用的回调方法的非阻塞方式 servlet内容可以不受阻塞地读取或写入。使用 ServletInputStream.setReadList ener(ServletInputStream,AsyncContext) 用ServletInputStream注册ReadListener的方法,并使用 I / O读取 ServletInputStream。的 setWriteListener 强>(ServletOutputStream的,AsyncContext) 注册WriteListener的方法。以下代码行 演示如何使用a注册ReadListener实现 ServletInputStream:
AsyncContext context = request.startAsync();
ServletInputStream input = request.getInputStream();
input.setReadListener(new ReadListenerImpl(input, context));
答案 1 :(得分:6)
利益不是直接 1 关于“绩效增益”。这些方法的目的是避免请求线程(在异步模式下)在读取输入(POST)数据或写入文档时阻塞。
Java EE7教程中有一个示例:"17.13.1 Reading a Large HTTP POST Request Using Non-Blocking I/O"(链接已更新)。
这与Tomcat在封面下使用nio是正交的。
1 - 有间接的性能优势。当线程可能阻塞网络I / O时,增加吞吐量的另一种策略是增加工作线程的数量。但这会增加内存占用(以及其他因素),从而导致更多“开销”。
答案 2 :(得分:3)
异步IO会在某些情况下对性能产生深远影响。我的经验主要是使用ASP.NET等效的,但它也应该适用于此。
servlet具有有限数量的线程来处理请求。如果存在任何类型的阻塞IO(网络请求,数据库查询等),则处理请求的线程在等待IO完成时仍在使用。在高容量方案中,这可能会使线程池匮乏并导致严重的性能下降。
使用异步IO,IO不会阻止请求线程。而是在IO完成时注册并随后调用回调。与此同时,线程返回到线程池,在那里它可以继续提供其他请求。