Non-Blocking IO and Tomcat
How Tomcat handles concurrent connections.
This page discuss a little bit about blocking/non-blocking IO and Tomcat in that context.
What is Blocking and Non-Blocking IO
Let’s consider the relationship between request HTTP connections and server threads allocated to process those connections.
In the first scenario, each request connection blocks a server thread, and only releases it when the server returns processing. This is called a Blocking I/O (since the thread is blocked to that connection until return).
The problem here is that we have a limited amount of threads to share with our HTTP clients. So, let’s say that we have 200 max threads to be shared. If we have a low latency (< 10ms), it is probably not a issue (since each thread is blocked for a very small period of time). But if you latency is about two seconds and yout throughput is 500 requests/second, you have a problem.
In that scenario, in the first second, 200 clients get connection and are waiting for the server to return. The other 300 clients get a “Connection Refused” and “Server Unavailable” (503) messages, and never get the connection.
So, let’s consider Non-Blocking I/O. In this scenario, the server gets a connection from the client, but do not block a thread. Instead, it holds the connection but alternate between threads to process the request, until return. In this scenario, more requests can be served.
How Tomcat Handles It
The default installation of Tomcat supports 200 simultaneous connections. This number can be increased in the maxThreads
attribute of a Connector
tag in the server.xml
file.
However, Tomcat also supports Non-Blocking I/O. It is said that it supports near 13,000 simultaneous requests in NIO mode.
Still, there is a limit. The acceptCount
attribute defines the maximum number of HTTP connections that will be put in a queue while there is no free connection available to serve.
Example
This tag is placed in config/server.xml
file:
<Connector URIEncoding="UTF-8" acceptCount="100" connectionTimeout="60000"
blankmaxHttpHeaderSize="8192" maxKeepAliveRequests="5000" maxThreads="200"
blankport="80" protocol="HTTP/1.1" redirectPort="8443"/>
In the example above, Tomcat is able to accept a maximum of 300
simultaneous requests before start refusing connections, returning HTTP Status Code 503
messages. That is because, based on parameters, it can handle 200
requests and put 100
requests in a queue while wait for others to complete. These are default Tomcat values.