Netty is an asynchronous, event-driven network framework for building high-performance protocol servers and clients. It powers gRPC, Elasticsearch, and many other Java systems.

Core Concepts

Concept Description
EventLoop Thread that processes I/O events
EventLoopGroup Pool of EventLoops
Channel Connection to a network endpoint
ChannelHandler Processes I/O events
ChannelPipeline Chain of handlers
Bootstrap Helper to configure and start

Architecture

                      EventLoopGroup (Boss)
                    ┌──────────────────┐
Client ──connect──▶ │ EventLoop (accept)│
                    └────────┬─────────┘
                             │ register
                    EventLoopGroup (Worker)
                    ┌────────┴─────────┐
                    │ EventLoop 1      │──▶ ChannelPipeline
                    │ EventLoop 2      │     [Decoder → Handler → Encoder]
                    │ EventLoop 3      │
                    └──────────────────┘
  

TCP Server

  EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();

try {
    ServerBootstrap bootstrap = new ServerBootstrap();
    bootstrap.group(bossGroup, workerGroup)
        .channel(NioServerSocketChannel.class)
        .childHandler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) {
                ch.pipeline()
                    .addLast(new StringDecoder())
                    .addLast(new StringEncoder())
                    .addLast(new EchoServerHandler());
            }
        });

    ChannelFuture future = bootstrap.bind(8080).sync();
    future.channel().closeFuture().sync();
} finally {
    bossGroup.shutdownGracefully();
    workerGroup.shutdownGracefully();
}
  

Server Handler

  @ChannelHandler.Sharable
public class EchoServerHandler extends SimpleChannelInboundHandler<String> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) {
        ctx.writeAndFlush("Echo: " + msg);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("Error", cause);
        ctx.close();
    }
}
  

TCP Client

  EventLoopGroup group = new NioEventLoopGroup();
try {
    Bootstrap bootstrap = new Bootstrap();
    bootstrap.group(group)
        .channel(NioSocketChannel.class)
        .handler(new ChannelInitializer<SocketChannel>() {
            @Override
            protected void initChannel(SocketChannel ch) {
                ch.pipeline()
                    .addLast(new StringDecoder())
                    .addLast(new StringEncoder())
                    .addLast(new ClientHandler());
            }
        });

    Channel channel = bootstrap.connect("localhost", 8080).sync().channel();
    channel.writeAndFlush("Hello, Netty!");
    channel.closeFuture().sync();
} finally {
    group.shutdownGracefully();
}
  

Maven Dependency

  <dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-all</artifactId>
    <version>4.1.104.Final</version>
</dependency>
  

Netty vs Java NIO

Feature Java NIO Netty
API complexity High (Selector, Buffer) Simplified
Thread model Manual EventLoop built-in
Codec support Manual Built-in (String, JSON, Protobuf)
Backpressure Manual Built-in
Production use Rare directly Widely used

Common Use Cases

  • Custom TCP/UDP protocols
  • WebSocket servers
  • HTTP proxy/gateway
  • RPC frameworks (gRPC uses Netty)
  • Message broker internals (RocketMQ, ActiveMQ)

Best Practices

  • Always shut down EventLoopGroups gracefully
  • Mark handlers @Sharable only if thread-safe (no instance state)
  • Use appropriate codec handlers (String, ByteBuf, Protobuf) in the pipeline
  • Set read/write timeouts to detect dead connections
  • Prefer higher-level frameworks (Spring WebFlux, gRPC) unless you need custom protocols