简体   繁体   English

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

[英]What is the difference between Tomcat's BIO Connector and NIO Connector?

I would like to know the internals of the tomcat NIO connector. 我想知道tomcat NIO连接器的内部结构。 How exactly are threads used when we create a servlet that implements CometProcessor?Is it still one thread per connection? 当我们创建一个实现CometProcessor的servlet时,线程究竟是如何使用的呢?它仍然是每个连接一个线程吗?

From what I read, the conversation goes like this 从我读到的,谈话就像这样

  1. Client connects to a servlet 客户端连接到servlet

  2. Servlet hangs on to the connection till there is any data available to the connected client Servlet会挂起连接,直到连接的客户端可以获得任何数据

  3. When data is ready , the server writes to the httpResponse and flushes it. 数据准备就绪后,服务器会写入httpResponse并将其刷新。 This actually disconnects the connection? 这实际上断开了连接?

  4. Client sends another request which the server again hangs onto.. 客户端发送另一个服务器再次挂起的请求。

How many thread are used when this keeps happening? 当这种情况持续发生时会使用多少个线程?

NIO and Comet are completely unrelated: you can mix-and-match them. NIO和Comet完全不相关:你可以混合搭配它们。

Using the NIO (or APR for that matter) connector allows you to handle more requests with fewer threads due to the threading model. 使用NIO(或APR)连接器允许您通过线程模型处理更少的线程请求。 See http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#Connector_Comparison for a comparison between the Connectors. 有关连接器之间的比较,请参阅http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#Connector_Comparison

Comet (and Websocket) have a completely different dispatch model which requires a different application architecture and achieves higher throughput in a different way. Comet(和Websocket)有一个完全不同的调度模型,它需要不同的应用程序架构,并以不同的方式实现更高的吞吐量。

The scenario you pose in your question is the typical blocking one-thread-per-request model. 您在问题中提出的方案是典型的阻塞单线程每请求模型。 In step 4, the Java BIO connector (which is the default up through Tomcat 7) will continue to wait for additional requests on the existing connector -- for keepalive HTTP requests. 在步骤4中,Java BIO连接器(默认情况下通过Tomcat 7)将继续等待现有连接器上的其他请求 - 用于keepalive HTTP请求。 If the client does not set Connection:close on the previous request and does not close the connection, the thread will hang until the keepalive timeout is reached. 如果客户端未设置Connection:close上一个请求并且未关闭连接,则线程将挂起,直到达到keepalive超时。 If you use the NIO connector, the thread will go back into the thread pool immediately after the response is sent and you won't "waste" a thread on keepalive requests that may never arrive. 如果您使用NIO连接器,线程将在发送响应后立即返回到线程池中,并且您不会“浪费”线程对可能永远不会到达的keepalive请求。

Comet/Websocket works entirely differently by delivering a message to a specially-written servlet (and optional filters) and the threads are only used when there are messages to send or data to be written. Comet / Websocket通过向特殊编写的servlet(和可选的过滤器)传递消息完全不同,并且仅在有要发送的消息或要写入的数据时使用线程。

UPDATE 2016-08-19 更新2016-08-19

Tomcat 8.5 and 9.0 have completely dropped the BIO connector. Tomcat 8.5和9.0已完全删除了BIO连接器。 This is because many of the new APIs and technologies (eg Websocket) require non-blocking semantics, and building a non-blocking service on top of a blocking API is very very difficult. 这是因为许多新的API和技术(例如Websocket)需要非阻塞语义,并且在阻塞API之上构建非阻塞服务非常困难。 The code required to get the job done was making the rest of the Tomcat code very ugly, etc. and so the decision was made to drop the BIO connector completely. 完成工作所需的代码是使其余的Tomcat代码非常难看等等,因此决定完全放弃BIO连接器。 So for Tomcat 8.5 and onward, only NIO, NIO2, and the APR-based connectors are available. 因此,对于Tomcat 8.5及更高版本,只有NIO,NIO2和基于APR的连接器可用。

Note that, also with Tomcat 8.5 and 9.0, support for Comet has been dropped. 请注意,同样使用Tomcat 8.5和9.0,已经删除了对Comet的支持。 Uses of Comet should all be replaced with Websocket which is a more standard protocol. Comet的使用都应该用Websocket代替,Websocket是一种更标准的协议。

NIO use fewer thread, it means that the tcp/ip port use is fewer. NIO使用更少的线程,这意味着使用更少的tcp / ip端口。

You know the port is 1 to 65534, so we can say that NIO can reach a higher TPS (Transactions Per Second) than BIO 你知道端口是1到65534,所以我们可以说NIO可以达到比BIO更高的TPS(每秒事务数)

I tested both protocol :HTTP/1.1 and org.apache.coyote.http11.Http11NioProtocol with same web-project, same host, and same server.xml but the protocol. 我测试了两个协议:HTTP/1.1org.apache.coyote.http11.Http11NioProtocol与相同的web项目,相同的主机和相同的server.xml但协议。

Use jmeter for test. 用jmeter进行测试。

I set 1000 thread to run request, when HTTP/1.1 in a few minutes, the host use port is more than 30000 and the TPS is 300 only! 我设置1000个线程来运行请求,当HTTP / 1.1在几分钟内,主机使用端口超过30000而TPS只有300!

When org.apache.coyote.http11.Http11NioProtocol, the max count of use port is never overstep 3000 and the tps is more than 1200! 当org.apache.coyote.http11.Http11NioProtocol时,使用端口的最大数量永远不会超过3000并且tps超过1200!

Adding late to this discussion - In this context of performance comparisons between blocking IO and Asynchronous NIO - an excellent read is "Old way of writing servers is new" . 在这个讨论的后期添加 - 在阻塞IO和异步NIO之间的性能比较的上下文中 - 一个很好的读取是“旧的编写服务器的方式是新的” In summary below thread per connection model was found to be better performing and easy to write as compared to the NIO version - contrary to the popular belief. 总的来说,与NIO版本相比,下面发现每个连接模型的性能更好,更容易编写 - 与流行的看法相反。

Here are two good articles on the NIO connector in case this helps someone considering the differences between BIO (request processing is bound to accept thread) & NIO (request processing is passed onto another worker thread) in Tomcat. 这里有两篇关于NIO连接器的好文章,以防有人在Tomcat中考虑BIO(请求处理必须接受线程)和NIO(请求处理被传递到另一个工作线程)之间的差异。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM