具有阻止应用程序的Tomcat NIO连接器

Boz*_*zho 14 java tomcat asynchronous

在阅读了Tomcat NIO连接器之后,我仍然没有得到一件事:如果应用程序代码阻塞,nio连接器是否有用,即在读取文件系统时,在调用外部Web服务时阻止从数据库读取?

因此,例如,您有一个类似REST的API,它接收请求,从数据库中读取内容并返回响应.它不使用servlet 3异步,它只是写入响应.

我没有找到NIO连接器使用的线程池的完整描述,但我想它有一个用于处理请求的线程池,因此每个请求最终都在它自己的线程中,它可以阻塞.

如果是这种情况,NIO的好处是否仍然存在,或者阻止代码会降低NIO的好处(在资源利用方面)?

Ber*_*sch 10

如果应用程序代码阻塞,nio连接器是否有用......?

是的,NIO连接器的构建假设您的应用程序将阻塞某处.NIO连接器基本上有几个套接字占位符,并响应新的传入请求,直到信息开始被写回.

我没有找到NIO连接器使用的线程池的完整描述

我认为这是你困惑的开始.Tomcat NIO有一个选择器池,而不是一个线程池(引用).连接器代码轮询每个选择器以查看它是否有要发送的传入或传出字节.从这个意义上讲,给定请求的选择器将继续接收信息,直到有足够的处理请求的请求/响应对象为桥接同步I/O和异步I/O(引用)之间的差距.

轮询代码永远不会阻塞比序列化信息包所花费的时间更长的时间,因此可以自由处理新请求.唯一真正的限制是Tomcat可用的内存量.虽然存在线程池,但使用的实际线程数远低于应用程序可以处理的连接数(引用).

虽然Tomcat连接器(引用)之间存在性能差异,但当servlet本身阻塞时,原始请求/响应时间的差异非常小.但是,当您使用非阻塞I/O时,Tomcat可以处理的并发请求数量的差异会有很大差异.

  • @AlexR,他们每个_currently处理request_有一个线程.Tomcat可以监听1000个传入请求,但一次只能处理100个.多余的传入请求将排队并尽快处理.唯一的区别是在Tomcat为Servlet使用线程之前,所有请求数据都已完全接收. (4认同)
  • 那么,在这种情况下ThreadLocal会发生什么?如果套接字被模拟并且在多个请求之间共享相同的线程,则在使用ThreadLocal时可能会产生不匹配.但事实上这并没有发生.Tomcat(可能还有其他容器)如何解决这个问题? (3认同)
  • @BerinLoritsch,虽然我同意你在网络应用程序中使用ThreadLocal,但即便是一些流行的框架也会这样做.例如,Spring将身份验证和数据库连接相关信息存储到本地线程中,这会在尝试异步执行某些操作时导致问题.但是当没有完成异步操作时,IMHO threadlocal运行良好,所以它们如何实现这一点非常有趣? (3认同)
  • 为此,您需要异步servlet方法 - 这需要您重新考虑很多事情(即您不能再可靠地使用ThreadLocal) (3认同)
  • 这意味着如果(如Bozho所说)应用程序执行REST请求或在其流程中间转向DB,则线程将被阻止,并且不会被重用于处理其他请求.如果在执行此类请求时可以将线程返回池中,那将很酷. (2认同)