- Leading Netty effort at Red Hat
- Vert.x / NIO / Performance
- Author of Netty in Action
- @normanmaurer
- github.com/normanmaurer
Netty is a NIO client server framework which enables quick and easy development of network applications …
Netty Website

Don’t call us, we’ll call you.
Hollywood principle
| Usually a Thread takes memory from 256kb to 1mb for the stack space! Also a lot of wasted resources… |
http://www.flickr.com/photos/bibi/5204647994/
| Once a `Channel was closed it can’t be reused. |
You can even deregister / re-register a Channel! |
ByteBuf buf = ...;
buf.writeInt(1).writeBytes(data).writeBoolean(true)...| Pooling pays off for direct and heap buffers! |
https://blog.twitter.com/2013/netty-4-at-twitter-reduced-gc-overhead

ChannelInboundHandlervoid channelRegistered(...) throws Exception;
void channelUnregistered(C...) throws Exception;
void channelActive(...) throws Exception;
void channelInactive(...) throws Exception;
void channelRead(...) throws Exception;
void channelReadComplete(...) throws Exception;
void userEventTriggered(...) throws Exception;
void channelWritabilityChanged(...) throws Exception;
void exceptionCaught(...) throws Exception;| These methods are called once there is something to handle by netty itself. |
ChannelOutboundHandlervoid bind(..., ChannelPromise promise) throws Exception;
void connect(..., ChannelPromise promise) throws Exception;
void disconnect(..., ChannelPromise promise) throws Exception;
void close(..., ChannelPromise promise) throws Exception;
void deregister(..., ChannelPromise promise) throws Exception;
void read(...) throws Exception;
void write(..., ChannelPromise promise) throws Exception;
void flush(...) throws Exception;These methods are called once a User requests some action via for example Channel.close(...). |
| Helps against GC pressure… |
http://25.media.tumblr.com/tumblr_me2eq0PnBx1rtu0cpo1_1280.jpg
@Sharable
public class EchoHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) { (1)
ctx.writeAndFlush(msg);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { (2)
cause.printStacktrace();
ctx.close();
}
}| 1 | Intercept received message and write it back to the remote peer |
| 2 | React on Throwable and close the connection |
| ByteToMessageDecoder |
Bytes → Pojo with handling of bufferingpublic class ByteToMessageDecoderImpl extends ByteToMessageDecoder {
@Override
public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) { }
}| MessageToMessageDecoder |
Pojo → Pojopublic class MessageToMessageDecoderImpl extends ByteToMessageDecoder<Pojo> {
@Override
public void decode(ChannelHandlerContext ctx, Pojo in, List<Object> out) { }
}| MessageToByteEncoder |
Pojo → Bytespublic class MessageToByteEncoderImpl extends MessageToByteEncoder<Pojo> {
@Override
public void encode(ChannelHandlerContext ctx, Pojo in, ByteBuf out) { }
}| MessageToMessageEncoder |
Pojo → Pojopublic class MessageToMessageEncoderImpl extends MessageToMessageEncoder<Pojo> {
@Override
public void encode(ChannelHandlerContext ctx, Pojo in, List<Object> out) { }
}ChannelHandlersKind of a unix-pipe-like thing…$ echo "Netty is shit...." | sed -e 's/is /is the /'
Netty is the shit....
| You see, everything is adjustable! |
Events move through the ChannelPipeline
Channel ch = ...;
ChannelPipeline p = ch.pipeline();
EventExecutor e1 = new DefaultEventExecutor(16);
EventExecutor e2 = new DefaultEventExecutor(8);
p.addLast(new MyProtocolCodec()); (1)
p.addLast(e1, new MyDatabaseAccessingHandler()); (2)
p.addLast(e2, new MyHardDiskAccessingHandler()); (3)| 1 | Executed in EventLoop (and so the Thread bound to it) |
| 2 | Executed in one of the EventExecutors of e1 |
| 3 | Executed in one of the EventExecutors of e2 |
http://www.flickr.com/photos/stavos52093/9645884201/
Channels| No need to worry about synchronization |
http://www.flickr.com/photos/za3tooor/65911648/
Multiple Channels are assigned to one EventLoop
ScheduleExecutorService goodies for free!
public class WriteTimeOutHandler extends ChannelOutboundHandlerAdapter {
@Override
public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) {
ctx.write(msg, promise);
if (!promise.isDone() {
ctx.executor().schedule(new WriteTimeoutTask(promise), 30, TimeUnit.SECONDS); (1)
}
}
}| 1 | Schedule task for in 30 seconds |
ServerBootstrap b = new ServerBootstrap();
EventLoopGroup group = new NioEventLoopGroup(numThreads);
try {
b.group(group, group)
.channel(NioServerSocketChannel.class)
.localAddress(new InetSocketAddress(25))
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new YourChannelHandler());
}
});
ChannelFuture f = b.bind().sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}Bootstrap b = new Bootstrap();
EventLoopGroup group = new NioEventLoopGroup(numThreads);
try {
b.group(group)
.channel(NioSocketChannel.class)
.remoteAddress(new InetSocketAddress("10.0.0.1", 25))
.handler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) {
ch.pipeline().addLast(new YourChannelHandler());
}
});
ChannelFuture f = b.connect().sync();
f.channel().closeFuture().sync();
} finally {
group.shutdownGracefully();
}
| Can be used for maximal performance on Linux |
Channel re-registerForkJoinPool based EventLoopSSLEngine| Check issue tracker to stay up-to-date. |
https://github.com/netty/netty/issues
| … and many more … |
| … and many more … |
http://www.flickr.com/photos/legofenris/4499417549/
| Mailinglist - https://groups.google.com/forum/#!forum/netty |
| IRC - #netty irc.freenode.org |
| Website - http://netty.io |
| Source / issue tracker - https://github.com/netty/netty/ |
| Buy my book Netty in Action and make me RICH. |
http://www.manning.com/maurer
$ KA-CHING $
| Netty - http://netty.io |
| Slides generated with Asciidoctor and DZSlides backend |
| Original slide template - Dan Allen & Sarah White |
All pictures licensed with Creative Commons Attribution orCreative Commons Attribution-Share Alike |