On 27/01/2012 23:16, bxqdev wrote:
>>> 2. async servlet api is not much usefull for servers, with nio
>>> connectors (tomcat-7). at least you can't image the case.
>>
>> I don't say that. In fact, I said exactly the opposite.
> 
> well, then what's the case to use both of this technologies? can you
> make up a theoretical case for an example?

Yes. See below.

>>> 3. async servlet api is some general technology to decouple client from
>>> server, when server doesn't have nio connector (server is bio-only).
>>
>> No. The Servlet Async API and the considerations for when one might use
>> it are completely orthogonal to connector selection.
> 
> how is that? both connector and servlet process user http request. one
> by one. how are they orthogonal?

The Servlet API, including the Async API only provides blocking IO.

I will ignore the APR/native connector since that just complicates
things further and just consider the BIO and NIO connectors below.

The fundamental difference is that BIO requires one thread per
connection whereas NIO requires one thread per currently processing
request plus a few threads for the pollers. Each poller can monitor
several thousand connections.

Therefore in a situation where you have many more connections than you
have current requests (think lots of HTTP keep-alive) then NIO scales
significantly better than BIO. The (very small) price you pay is
performance since using a poller adds overhead to request processing.

[1] shows that the NIO connector uses non-blocking IO where it can but
as soon as it enters the realm of the Servlet API (reading the request
body and writing the request response) it has to simulate blocking IO.

There is actually a complication to BIO in newer versions of Tomcat.
Rather than dedicating one thread to a connection, each time Tomcat
needs to read from a connection (remember this is blocking IO and there
might not be anything to read if the connection is in keep-alive but the
thread will then block until some data turns up or the connection times
out) Tomcat obtains a thread from an executor. This raises the
possibility of having more connections than you have threads. With BIO
that is usually bad and results in unexpected delays in processing
requests but as we'll see shortly, there are times (not many) where it
might be useful.


Prior to the Servlet 3.0 Async API a single container thread was
responsible for all of the processing associated with a request.

A few points to note at this point:
- All IO is still blocking IO
- The async API is only for writing data to the response. There is no
"async" reading of data from the client.

A typical usage of the Servlet 3.0 Async API is as follows:
- request processing starts as usual on a container thread
- async is started
- the container thread is returned to the container's thread pool
- processing continues on an application thread
- the application writes some data to the response
- the application passes the response back to the container for the
container to finish it off on a container thread

The purpose of the Servlet 3.0 Async API is to remove the one thread per
currently processing request constraint.

This allows applications to do things like:
- implement a stock ticker with one thread writing to many responses
(rather than one thread per response)
- implement a chat program with one thread writing to all the clients
(rather than one thread per response)

If applications relay on external resources that are known to take a
long time to respond, prior to the Async API developers had no choice
but to simply block waiting for the external resource to respond. With
the Async API, a single thread can monitor an external resource on
behalf of many requests and only dispatch the request/response pair to a
container thread for processing when the external resource has replied.
This allows for more efficient use of container threads.

Now back to the BIO complication. Lets say you have 100 container
threads configured on your BIO connector and you are absolutely sure
that at any one time 20% of your incoming connections would be using
Servlet 3 Async and would be being handled by an application thread then
you could set maxConnections to 120 and service 120 users in parallel.
Your assumption regarding the 20% was wrong then you would see
potentially long delays in processing incoming requests as connections
with data were waiting for a container thread to become available to
process it.


So back to my original point. BIO vs NIO and Servlet 3 Sync vs Async are
solving orthogonal problems.

If you use an NIO connector that doesn't help you write a chat
application more efficiently. You would still need one thread per
client. For that you need the Servlet 3.0 Async API.

The Async API does not help you efficiently handle many thousands of
connections when the majority of them are in HTTP keep-alive. For that
you need the NIO connector.

Different problems, different solutions.

>> I am getting rather bored with this. Please go and read up on blocking
>> IO vs. non-blocking IO and then read the Async parts of the Servlet 3.0
>> specification. Then come back here and try asking some more focussed
>> questions.
> 
> i completely understand the difference of bio vs. nio. and i've already
> read async servlet spec.

Clearly that is not the case. If it were, we wouldn't be having this
conversation.

> both technologies decouple (make async) input and output. but i can't
> imagine the case when the one
> would need two points of decoupling on one processing chain.

That is because you failed to understand what the two different
technologies were doing.

> 1. bio connector & sync servlet
> 1.1 i guess everything is obvious
Apparently not.

> 2. bio connector & async servlet
> 2.1 bio connector receives request and synchronously handles it to async
> servlet
> 2.2 async servlet starts async processing code and returns.
> 2.3 bio connector waits async servlet to finish
Not correct. See comments re executor above. The BIO connector will not
try to read from the connection until after the response has been
completed (step 2.5 below).

> 2.4 async servlet fullfills response
> 2.5 bio connector returns servlet to client
It is the response that is returned, not the servlet.

> 3. nio connector & sync servlet
> 3.1 nio connector makes select and receives http request
> 3.2 nio connector handles request to sync servlet
> 3.3 sync servlet processes request and return response
> 3.4 nio connector makes select and receives http response from sync servlet
Not correct. All IO is required to be blocking at this point. See [1]
and comments above on simulated blocking.

> 3.5 nio connector returns servlet to client
Again, it is the response rather than the servlet that is returned.

> 4. nio connector & async servlet
> 4.1 nio connector makes select and receives http request
> 4.2 nio connector handles request to async servlet
> 4.3 async servlet starts async processing code.
> 4.4 async servlet fullfills response
> 4.5 nio connector makes select and receives http response from async
> servlet
Not correct. All IO is required to be blocking at this point. See [1]
and comments above on simulated blocking.

> 4.6 nio connector returns servlet to client
Again, it is the response rather than the servlet that is returned.

> uh, that was a lot of typing :)

You don't appear to understand the relationships between the blocking IO
APIs provided in the Servlet API and how that data gets to the socket
(via a few buffers). It looks like you are assuming that the servlet
processing and the connectors exist in separate components with separate
thread pools and some form of IO connection between them. That is not
the case (and would be pointless and hopelessly inefficient since the
Servlet API uses blocking IO). It is the threads from the connector
thread pool that are responsible for the request processing.

Mark


[1]
http://tomcat.apache.org/tomcat-7.0-doc/config/http.html#Connector_Comparison


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to