Remy Maucherat wrote:
Jeanfrancois Arcand wrote:
I disagree ;-) I would like to see your implementation, because from what I'm seeing/measuring, it is completely the inverse. I would be interested to see how you did implement your NIO connector. The problem with HTTP is not NIO, but the strategy to use for predicting if you have read all the bytes or not. Falling to implement a good strategy will ends up parsing the bytes many times, calling the Selector.wakeup() too often, thus poor performance. The way you register your SelectionKey is also very important.
Also, blocking IO required 1 thread per connection, which doesn't scale very well. That's why I think the new APR connector is interesting, since it fix that problem. But even if with APR, you did workaround the JNI bottleneck by using direct byte buffer, I suspect a pure NIO implementation will perform better than APR (except for static resource) just because of the C->Java overhead. But I don't have yet numbers to show...come to my session at JavaOne, I will :-)
Sorry, but I agree with Mladen. There is simply no way a pure non blocking NIO strategy is going to work. It is an attempt to apply receipes which work really well for certain types of takss to other types of tasks. Translated, it would work spectacularly well for, say, a servlet like the default servlet and a small file (ie, small bufferable amount of data + no processing), but fail for a servlet which receives a lot of uploading or more generally has a long processing time. The main problem is that to keep contention on IO low, a low amount of processors has to be used, which is not compatible with the second type of tasks. The only way to apply NIO to Tomcat is to use it in blocking mode, as in the submitted patch.
Well, the strategy you use is important. If you can predict the size of the stream (by let say discovering the content-length), you can make uploading task as fast as with blocking IO (OK, maybe a little slower since you parse the header, and the channel may not reads it fully in its first Selector.select()). But for GET operation, it shouldn't be a problem.
The only way to convince me your solution can work is to (also) write your own endpoint / protocol handler (this seems trendy these days for some reason, so I guess it's ok if everyone does it ;) ) so I can test it myself and see the results.
Right, I agree this is the way to go ;-). Replacing the current thread pool doesn't hurt also (but maybe it's only me..this pool is way to complex for what it does).
As APR matches the numbers of classic blocking IO in the (100% throughput oriented, and worst case; at least, it's the case which favors regular blocking IO the most) ab -k -c 20 localhost/tomcat.gif, it seems hard to beat.
Well, I agree but I'm not really interested about static resource. I'm more interested to benchmark a real JSP/Servlet application, that contains both static and dynamic resources. I think APR will always be faster that NIO non blocking for static resources. But non blocking will be faster than the current Coyote/http11 connector, by applying the same trick you did for DefaultServlet sendFile implementation, and by using MappedByteBuffer to load the resource in FileDirContext.
But all I'm saying needs numbers, which I will have in June :-)
<rant>
BTW, about the NIO usage for optimizing JNI, I'm actually really mad about Sun.
Haha. Have you ever be happy with SUN :-) Probably only the day you hired me (LOL) and asked me to implement XML schema supports (beurk!) :-)
Why attempt to make any JNI calls "safe" and make performance
suck in the first place, when with native code usage it is trivial to segfault the whole process anyway (example: feed APR a bad address) ?
I agree. But seems the "safe" lobbyist were stronger that others...
This really makes no sense to me, and seems simply a plot to try to force people to write 100% Java code.
All that complexity and crappy performance for *nothing* (except helping .not and mono, of course) ...
</rant>
You may tray that simply by using demo HTTP servers Blocking/Blocking Pool/NIO single thread/NIO multiple threads that comes with new Java6 (see java.net for sources).
Right. This is actually a good example not to follow ;-).
BTW the big patch use NIO blocking, which may improve scalability, but will impact throughput. The patch should be improved to use NIO non-blocking. And then we can compare ;-)
You're going to have to prove your point in a big way ;)
Yes, this is exactly what I will try to do at JavaOne. I'm waiting for APR to stabilize before predicting anything. If APR is faster, then good. But I think we need to compare a real NIO implementation, not a hack inside the current http11 code. And I still think non-blocking is better.
There were
articles on the subject advocating the same thing, but if you looked a little into it, you could just see how to make the whole thing break really easily.
I agree...but the strategy used just sucks. Having a pipe between the Read Thread and the Processor Thread might looks good on paper, but that's clearly not a good strategy. Also the NIO implementation in Jetty is clearly bad. EmberIO framework looked promising, but seems little activity happenned after the big annoncement....
Still, if APR is faster, then I will say it is. But to convince me, I need to compare real implementation.
Thanks
-- Jeanfrancois
Rémy
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]