Netty - The async event-driven network application framework

Norman Maurer, Principal Software Engineer @ Red Hat Inc

  • Leading Netty effort at Red Hat
  • Vert.x / NIO / Performance
  • Author of Netty in Action
  • @normanmaurer
  • github.com/normanmaurer

Agenda

  • What is Netty
  • Features
  • Buffers
  • EventLoop

What is Netty ?

Netty is a NIO client server framework which enables quick and easy development of network applications …


Netty Website

Features Netty comes with…

components

Overview

  • Asynchronous
  • Unified API
  • High-Performance
  • Buffer Pooling
  • Gathering / Scattering

Asynchronous and non blocking by nature

  • I/O Operations don’t block at all!
  • Notified later
  • Share one Thread

Don’t call us, we’ll call you.


Hollywood principle

But why non-blocking at all ?

Usually a Thread takes memory from 256kb to 1mb for the stack space! Also a lot of wasted resources…
ouch
http://www.flickr.com/photos/bibi/5204647994/

Transports - We have a lot of them!

  • NIO
  • OIO
  • Local
  • Embedded
  • Native (only on linux)

Supported transport protocols

  • TCP
  • UDP (Datagram / Multicast)
  • UDT
  • Serial
  • SCTP (only on linux)

Simple state model

state
Once a `Channel was closed it can’t be reused.

States during lifetime of a Channel

state 2
You can even deregister / re-register a Channel!

ByteBuf - ByteBuffer on steroids!

  • Separate index for reader/writer
  • Direct, Heap and Composite
  • Resizable with max capacity
  • Reference counting
ByteBuf buf = ...;
buf.writeInt(1).writeBytes(data).writeBoolean(true)...

ByteBuf pooling to reduce allocation / deallocation time!

Pooling pays off for direct and heap buffers!
pooled buffers
https://blog.twitter.com/2013/netty-4-at-twitter-reduced-gc-overhead

ChannelHandler - Where your handling logic lives

  • Inbound and Outbound
  • Called by the `EventExecutor
channel handlers

ChannelHandler - Use cases

  • Convert data
  • Business logic
  • React on state changes

ChannelInboundHandler - Events to handle

ChannelInboundHandler
void 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.

ChannelOutboundHandler - Events to handle

ChannelOutboundHandler
void 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(...).

Calling methods directly vs. fire event objects

Helps against GC pressure…
gc pressure
http://25.media.tumblr.com/tumblr_me2eq0PnBx1rtu0cpo1_1280.jpg

ChannelHandler in Action

@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();
  }
}
1Intercept received message and write it back to the remote peer
2React on Throwable and close the connection

Provided Encoder / Decoder

  • HTTP / HTTP2 (*WIP)
  • WebSockets
  • SPDY
  • SSL / TLS
  • Serialization
  • GZip / Deflate

Decoder base classes ⇒ Inbound

ByteToMessageDecoder
Bytes → Pojo with handling of buffering
public class ByteToMessageDecoderImpl extends ByteToMessageDecoder {
  @Override
  public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) { }
}
MessageToMessageDecoder
Pojo → Pojo
public class MessageToMessageDecoderImpl extends ByteToMessageDecoder<Pojo> {
  @Override
  public void decode(ChannelHandlerContext ctx, Pojo in, List<Object> out) { }
}

Encoder base classes ⇒ Outbound

MessageToByteEncoder
Pojo → Bytes
public class MessageToByteEncoderImpl extends MessageToByteEncoder<Pojo> {
  @Override
  public void encode(ChannelHandlerContext ctx, Pojo in, ByteBuf out) { }
}
MessageToMessageEncoder
Pojo → Pojo
public class MessageToMessageEncoderImpl extends MessageToMessageEncoder<Pojo> {
  @Override
  public void encode(ChannelHandlerContext ctx, Pojo in, List<Object> out) { }
}

Generic useful Decoders

  • ReplayDecoder
  • FixedLengthFrameDecoder
  • LengthFieldBasedFrameDecoder
  • LineBaseFrameDecoder
  • DelimiterBasedFrameDecoder

ChannelPipeline - Assemble ChannelHandlers

  • Holds ChannelHandlers
  • Per `Channel
  • Events pass through
  • On-the-fly-modifications
Kind 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!

ChannelPipeline - How does it work

channel pipeline
Events move through the ChannelPipeline

ChannelPipeline in Action

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)
1Executed in EventLoop (and so the Thread bound to it)
2Executed in one of the EventExecutors of e1
3Executed in one of the EventExecutors of e2

EventLoop - Someone needs to do the heavy work

event loop
http://www.flickr.com/photos/stavos52093/9645884201/

EventLoop - Facts

No need to worry about synchronization
thumb up 2
http://www.flickr.com/photos/za3tooor/65911648/

EventLoop - Assigned to Channels

eventloop channel
Multiple Channels are assigned to one EventLoop

EventLoop - All the ScheduleExecutorService goodies for free!

eventexecutor
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)
    }
  }
}
1Schedule task for in 30 seconds

Bootstrap - Start and stop Netty applications

ServerBootstrap

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

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();
}

Native Epoll Transport

200px Tux.svg
Can be used for maximal performance on Linux

Things to come

Check issue tracker to stay up-to-date.
https://github.com/netty/netty/issues

Companies using Netty!

companies
… and many more …

(Opensource) Projects using Netty!

projects
… and many more …

We love Contributions!

empire wants you 2
http://www.flickr.com/photos/legofenris/4499417549/

Get Involved - We love contributions

netty logo
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/

Want to know more?

Buy my book Netty in Action and make me RICH.
maurer cover150
http://www.manning.com/maurer

$ KA-CHING $

References

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 or
Creative Commons Attribution-Share Alike

Norman Maurer