- 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
BadchannelIdle(ctx, new IdleStateEvent(
IdleState.READER_IDLE, readerIdleCount ++, currentTime - lastReadTime));GoodchannelIdle(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...
Badpublic void suspendRead() {
if ((ops & ey.interestOps()) != 0) {
key.interestOps(key.interestOps() & ~OP_READ);
}
}Goodint 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 helpsprivate 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 |
Badprivate volatile Selector selector;
public void method() {
selector.select();
....
selector.selectNow();
}Goodprivate 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