Tomcat的BIO连接器和NIO连接器有什么区别?

use*_*150 54 tomcat nio

我想知道tomcat NIO连接器的内部结构.当我们创建一个实现CometProcessor的servlet时,线程究竟是如何使用的呢?它仍然是每个连接一个线程吗?

从我读到的,谈话就像这样

  1. 客户端连接到servlet

  2. Servlet会挂起连接,直到连接的客户端可以获得任何数据

  3. 数据准备就绪后,服务器会写入httpResponse并将其刷新.这实际上断开了连接?

  4. 客户端发送另一个服务器再次挂起的请求.

当这种情况持续发生时会使用多少个线程?

Chr*_*ltz 56

NIO和Comet完全不相关:你可以混合搭配它们.

使用NIO(或APR)连接器允许您通过线程模型处理更少的线程请求.有关连接器之间的比较,请参阅http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#Connector_Comparison.

Comet(和Websocket)有一个完全不同的调度模型,它需要不同的应用程序架构,并以不同的方式实现更高的吞吐量.

您在问题中提出的方案是典型的阻塞单线程每请求模型.在步骤4中,Java BIO连接器(默认情况下通过Tomcat 7)将继续等待现有连接器上的其他请求 - 用于keepalive HTTP请求.如果客户端未设置Connection:close上一个请求并且未关闭连接,则线程将挂起,直到达到keepalive超时.如果您使用NIO连接器,线程将在发送响应后立即返回到线程池中,并且您不会"浪费"线程对可能永远不会到达的keepalive请求.

Comet/Websocket通过向特殊编写的servlet(和可选的过滤器)传递消息完全不同,并且仅在有要发送的消息或要写入的数据时使用线程.

更新2016-08-19

Tomcat 8.5和9.0已完全删除了BIO连接器.这是因为许多新的API和技术(例如Websocket)需要非阻塞语义,并且在阻塞API之上构建非阻塞服务非常困难.完成工作所需的代码是使其余的Tomcat代码非常难看等等,因此决定完全放弃BIO连接器.因此,对于Tomcat 8.5及更高版本,只有NIO,NIO2和基于APR的连接器可用.

请注意,同样使用Tomcat 8.5和9.0,已经删除了对Comet的支持.Comet的使用都应该用Websocket代替,Websocket是一种更标准的协议.

  • 听起来NIO是双赢的,所以为什么BIO在APR不可用时是默认的? (4认同)
  • @Jayen BIO是Tomcat到7.0.x的默认连接器.在Tomcat 8中,NIO是[默认连接器](http://tomcat.apache.org/migration-8.html#Default_connector_implementation). (4认同)
  • @Jayen是的,它在Tomcat 6中仍然是实验性的,并且在Tomcat 7发布之后决定使NIO成为默认值.因此,不是更改点版本中的默认连接器并可能导致各种问题,而是在Tomcat 8中切换到NIO默认设置.任何人都可以随意明确地将其连接器更改为NIO ...这只是默认设置已经改变了,此时NIO连接器非常稳定. (3认同)