Netty Overview
Netty is an asynchronous event-driven network application framework for JVM, with the goal of making high-concurrency, high-throughput network program development as simple as writing ordinary business code. Internally, it uses a combination of Reactor/Proactor + thread pool, thoroughly encapsulating complex details like I/O multiplexing, buffer management, and protocol encoding/decoding, so developers only need to focus on business logic in ChannelHandler.
Structure Overview
- Channel: Socket abstraction, supporting multiple transports like NIO, Epoll, KQueue, io_uring, UDT, QUIC, etc.
- EventLoop/Group: Event loop thread, single-threaded serialization + task queue, naturally avoiding lock contention
- ChannelPipeline: Responsibility chain, inbound/outbound bidirectional flow, dynamic encoding/decoding, aggregation, encryption
- ByteBuf/Buffer: Memory model, direct memory pool, zero-copy, reference counting
Key Features
- Non-blocking I/O: Based on Selector (or epoll/kqueue/io_uring) for true asynchronous read/write
- Zero-copy optimization: CompositeByteBuf, FileRegion.sendfile() and TCP_CORK/TCP_NOPUSH
- Adaptive memory pool: PooledByteBufAllocator + ThreadLocal buffer to avoid GC pressure
- Rich protocol stack: Built-in HTTP/1.1, WebSocket, HTTP/2
- Platform native acceleration: Linux epoll, Mac kqueue, Windows IOCP
- Pluggable pipeline: Dynamic Handler addition/removal, Sharable annotation, Half-close, backpressure mechanism
Use Cases
- High-throughput RPC: gRPC-Java, Dubbo, Finagle all embed Netty
- Gateway and reverse proxy: Spring Cloud Gateway, Zuul-2
- Message/stream processing: Kafka (old version), Pulsar, Flink
- Gaming and IM: Low-latency long connections
POM Dependency
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.6.Final</version>
</dependency>
Server Code
package icu.wzk.netty;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
public class WzkNettyServer {
public static void main(String[] args) throws Exception {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap
.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel nioSocketChannel) throws Exception {
ChannelPipeline pipeline = nioSocketChannel.pipeline();
pipeline
.addLast(new StringEncoder())
.addLast(new StringDecoder())
.addLast(new SimpleChannelInboundHandler<String>() {
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
System.out.println("Custom handler: " + s);
}
});
}
});
ChannelFuture channelFuture = serverBootstrap.bind(8888).sync();
System.out.println("Server started");
channelFuture.channel().closeFuture().sync();
}
}
Client Code
package icu.wzk.netty;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import java.util.Date;
public class WzkNettyClient {
public static void main(String[] args) throws Exception {
Bootstrap bootstrap = new Bootstrap();
NioEventLoopGroup group = new NioEventLoopGroup();
bootstrap
.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel channel) throws Exception {
channel
.pipeline()
.addLast(new StringEncoder());
}
});
Channel channel = bootstrap.connect("127.0.0.1", 8888).channel();
while (true) {
channel.writeAndFlush(new Date() + " Hello!");
Thread.sleep(2000);
}
}
}
Test Program
Server running effect: After the server starts, it listens on port 8888. After receiving client messages, it prints “Custom handler: ” + message content.
Client running effect: The client sends a date-time message to the server every 2 seconds.