Jan-Henrik Haukeland wrote:
Remy Maucherat <[EMAIL PROTECTED]> writes:


My opinion is that NIO is going to be really useless.


Eh, hello!? Oh, okay if it's not important that Tomcat scale and
perform well it may be useless. But, really, before NIO it was
hopeless to try and write a scalable and fast tcp server application
in Java. Tomcat's current connection handling with blocing all over
the place and "thundering herd" problem doesn't scale or work very
well under heavy load.

Don't forget that servlets ( which is the main job of tomcat ) use blocking input/output streams.

NIO select ( which is what most people see first in NIO ) is not going to help in this. Select is extremely powerfull - but it requires a certain kind of event-based architecture which doesn't match the blocking model of servlets ( which has the big benefit of making things
simple for users ).


Think about it - in any case you do need one thread for each active request, for the servlet. Most of the time is spent in the service() method - you can do select() as much as you want in http/jk processing, but you must have the thread for service() ( which can't be avoided since servlets are allowed to block the thread ).

Only thing you can save is the static servlet - but for that you are better off using a real server or a cache.

It's sad people see select() first - and don't pay attention to char-byte convertors in NIO ( a huge ammount of optimization - tomcat
already has something that emulates the same model, so we won't benefit
much ), and the mmapping feature - which is huge for IPC and java-native
communication.


Costin



- It will make object reuse more complex (you'll have to have a pool
holding all the HTTP processors, essentially)


You will have a pool holding incomming connection, and if there is an
i/o event on the connection such as data present you will hand the
connection over to a small pool of HTTP processors (5-10). Here's a
quasi example for the main server loop. (All sockets must be
non-blocking, including the serversocket, i.e. it must *not* block on
accept(). Every i/o operation must of course also be non-blocking).

This loop allows the server to handle many thousand concurrent
connections without using many threads.

for(;;) {
/* Poll the connection pool, including the server socket and
* return the number of sockets ready for processing */
numReady= Poll.poll(); if(Poll.hasConnection()) { /* We have new connections on the server socket; accept
* every incomming connection and put them into the * connection pool */
doAccept();
/* Continue checking for more incomming connection;
* new connections are more important than old */
continue;
}
if(numReady == 0) {
/* Close and remove connections that has timed out or
* are done */
Poll.checkTimeout();
/* Continue checking for more incomming connection */
continue;
}
/* Get and process only those connections that is
* ready. I.e. has data avilable. (More optimizing is to only
* hand over incomming connection that has read and buffered a
* complete HTTP request */
while((connection= Poll.next())) {
/* Push the connection into our HttpProcessor thread
* worker/queue for processing. - Keep-alive connections are not closed but keept in
the connection pool and will be re-processed.
- Connections that are finished are closed by the
HttpProcessor and will be removed from the pool
in the test above */
if(! processorPush(connection)) {
/* If no more processor threads are available
* we process the request ourself. Alternatively * increase the pool of processor threads */
processConnection(connection, NO_KEEPALIVE);
}
}
}





--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to