On this page
Netty Basics
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
@Sharableonly 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