- Leading Netty effort at Red Hat
- Vert.x / NIO / Performance
- Author of Netty in Action
- @normanmaurer
- github.com/normanmaurer
For high-performance with many concurrent connections you WANT to use NIO or NIO.2! |
https://www.flickr.com/photos/theleetgeeks/3110958031
There are others but some are not exposed by java nio itself. |
http://25.media.tumblr.com/tumblr_me2eq0PnBx1rtu0cpo1_1280.jpg
Every time I hear allocation / deallocation of objects is a no-brainer a kitten dies! |
But only cache/pool where it really makes sense as long-living objects may be bad either in terms of GC |
Rule of thumb: use static if it’s immutable and used often. If its mutable only pool / cache if allocation costs are high! |
If you never saw GC-Pressure you not pushed your system hard enough
Famous words of myself
Bad
channelIdle(ctx, new IdleStateEvent(
IdleState.READER_IDLE, readerIdleCount ++, currentTime - lastReadTime));
Good
channelIdle(ctx, IdleStateEvent.READER_IDLE_EVENT);
See Netty issue #973 for more details. |
Stop the world == worst enemy! |
But zero-out byte[] of heap buffers is not for free either… |
Can't insert int here as we need 4 slots :(
A good pool will handle this! |
Pooling pays off for direct and heap buffers! |
https://blog.twitter.com/2013/netty-4-at-twitter-reduced-gc-overhead
Especially useful if "message" is assembled out of header and payload.
Use direct buffers for operations on SocketChannel … |
Why?
Confused developer
Internally OpenJDK/Oracle JDK will copy the buffer to a direct buffer if you use a heap buffer |
Syscalls are expensive, use them with care. |
Many methods on the SocketChannel map directly to a syscall. |
https://www.flickr.com/photos/theshadowknows/2995004692
Use ByteBuffer.slice() and ByteBuffer.duplicate() whenever possible. |
https://www.flickr.com/photos/pasukaru76/4350792315
Only possible if you not need to transform the data during transfer! |
interestedOps(…) == queue on network stack
http://memecrunch.com/meme/270NI/sparta-bird/image.png
But not call interestedOps(…) too often, it’s expensive. See #1024 |
Remember most of the times the Channel is writable. |
DNS lookup will block :(
InetSocketAddress remote = ...
remote.getAddress().getHostname();
Logging can be a culprint too … Async logging may be the key. |
RED == BAD |
… Whether or not it blocks, and for how long is implementation-dependent…
Javadocs of SelectionKey
Shit just got real...
Bad
public void suspendRead() {
if ((ops & ey.interestOps()) != 0) {
key.interestOps(key.interestOps() & ~OP_READ);
}
}
Good
int ops = key.interestOps();
if ((ops & OP_READ) != 0) {
key.interestOps(ops & ~OP_READ);
}
When write a System that handles 100k of concurrent connections every saved memory count for long-living objects
Hint of myself
Ugly but helps
private static final AtomicLongFieldUpdater<TheDeclaringClass> ATOMIC_UPDATER =
AtomicLongFieldUpdater.newUpdater(TheDeclaringClass.class, "atomic");
private volatile long atomic;
public void yourMethod() {
ATOMIC_UPDATER.compareAndSet(this, 0, 1);
}
Some more details on the topic on my blog post Lesser-known-concurrent-classes-Part-1 |
Bad
private volatile Selector selector;
public void method() {
selector.select();
....
selector.selectNow();
}
Good
private volatile Selector selector;
public void method() {
Selector selector = this.selector;
selector.select();
....
selector.selectNow();
}
Allocation / Deallocation of ByteBuffers is a lot faster these days |
There is always a trade-off. |
If you write your custom protocol think about Pipelining. |
https://www.flickr.com/photos/chiselwright/5169469959/
Attend my other talk later today! |
http://memegenerator.net/instance/43005548.... [.topic.source] == References NOTE: Slides generated with Asciidoctor and DZSlides backend NOTE: Original slide template - Dan Allen & Sarah White NOTE: All pictures licensed with `Creative Commons Attribution` or + `Creative Commons Attribution-Share Alike` [.topic.ending, hrole="name"] == Norman Maurer [.footer] [icon-twitter]'{zwsp}' @normanmaurer