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.