Hi Trustin,
Yes, I tried that as well - it didn't seem to make much difference,
though I guess that flag would be more useful over the Internet maybe?
There is a happy ending to this story, after much tuning and playing
around with JProfiler I managed to squeeze quite a bit more out of the
networking and smoke didn't pour out of the back of my machine! :)
On a 2Ghz AMD Atholon (3200+) running on Windows XP I can very
comfortably cope with 1000 simultaneous sessions. I'm sending 250 bytes
to each one of those every 250ms and they're responding with a 64 byte
packet. When I do this, my CPU utilisation is at around 40% which is
more than acceptable. I can even crank it up to 1500 simultaneous
sessions, though admittedly that does push the CPU utilisation up to
around 70-75%.
These are the tweaks that I'm using on the server:
ByteBuffer.setAllocator(new SimpleByteBufferAllocator());
ByteBuffer.setUseDirectBuffers(false);
Here's my acceptor:
acceptor = new
SocketAcceptor(Runtime.getRuntime().availableProcessors()+1,
Executors.newFixedThreadPool(50));
acceptor.getDefaultConfig().setThreadModel(ThreadModel.MANUAL);
acceptor.bind( new InetSocketAddress(port), this);
acceptor.addListener(this);
Part of the problem is simulating that number of connections from the
client machine. To achieve this, I created a single IoHandlerAdapter
and opened up multiple connections - that seems to work well providing
that you don't run the client on the same machine as the server. I used
a pooled byte buffer allocator for the client. Don't try to create an
instance of IoHandlerAdapter for each connection (I was doing this
originally - of course that created 1000s of threads causing a
bottleneck on the client).
I upgraded my entire project to JDK 1.5 as well as Mina 1.1 and that
seems to give a 5-10% increase in performance.
I absolutely minimise *any* complex operations in my IOHandlerAdapter
and associated classes. I found that HashMap lookups with this amount
of packets can be particularly expensive, as can creating byte arrays
(even tiny ones). I find that Mina session attributes are very useful.
I know all of that sounds obvious, but you'd be surprised how simple
little operations can stack up.
If you have to write a byte array to the IoHandler adapter, use
ByteBuffer.wrap(b) - this seems pretty fast.
I hope that might be useful for anybody else trying to do anything similar!
Cheers,
Richard.
--
Trustin Lee wrote:
Additionally, did you try to turn on 'tcp no delay' option? (this
doesn't affect CPU utilization but might improve throughput)
((SocketSessionConfig) cfg.getSessionConfig()).setTcpNoDelay(true);
and... It would be nice to see your IoHandler implementation code.
HTH,
Trustin