Understanding the Netty Server Startup Process
This article explains how Netty initializes and starts a server by detailing the creation of EventLoopGroups, the configuration of ServerBootstrap, the execution of channel(), handler(), childHandler(), and doBind() methods, and the handling of JDK selector bugs, illustrated with code and diagrams.
Netty is a Java NIO‑based network framework, and this article explores exactly when and how its server side is started, including the moments when register and bind are invoked and when data reading begins.
Using the official EchoServer example, the article first presents the complete startup code, which creates a boss EventLoopGroup , a worker EventLoopGroup , configures a ServerBootstrap , and finally binds the server to a port.
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer
() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline p = ch.pipeline();
p.addLast(new EchoServerHandler());
}
});
ChannelFuture f = b.bind(PORT).sync();The startup process consists of five key stages, with the most critical step occurring at the final bind call (step 5). To aid understanding, the article provides flow diagrams for each stage.
1. Initializing EventLoopGroup – The EventLoopGroup constructors chain up to AbstractEventExecutor , creating the core executor objects needed for handling I/O events.
2. Executing channel() – This method creates a ReflectiveChannelFactory that later produces the actual Channel instances.
3. Executing handler() – Assigns a user‑provided ChannelHandler to the bootstrap’s handler field for later use during initialization.
4. Executing childHandler() – Assigns the child ChannelHandler that will process inbound data on accepted connections.
5. Executing doBind() – The most complex step, split into initAndRegister() and doBind0() . initAndRegister() creates a channel via the factory, initializes it, and registers it with a JDK Selector . doBind0() performs the actual port binding, starts the event‑loop thread, and repeatedly calls Selector.select() to handle I/O events.
The article also discusses the JDK epoll empty‑poll bug and shows how Netty mitigates it by rebuilding the Selector after a configurable number of consecutive empty selects. A snippet of the selector loop illustrates the detection logic:
private void select(boolean oldWakenUp) throws IOException {
Selector selector = this.selector;
try {
int selectCnt = 0;
long currentTimeNanos = System.nanoTime();
long selectDeadLineNanos = currentTimeNanos + delayNanos(currentTimeNanos);
for (;;) {
long timeoutMillis = (selectDeadLineNanos - currentTimeNanos + 500000L) / 1000000L;
if (timeoutMillis <= 0) {
if (selectCnt == 0) {
selector.selectNow();
selectCnt = 1;
}
break;
}
int selectedKeys = selector.select(timeoutMillis);
selectCnt++;
if (selectedKeys != 0 || oldWakenUp || wakenUp.get() || hasTasks()) {
break;
}
// Rebuild selector if empty‑poll threshold exceeded
if (SELECTOR_AUTO_REBUILD_THRESHOLD > 0 && selectCnt >= SELECTOR_AUTO_REBUILD_THRESHOLD) {
rebuildSelector();
selector = this.selector;
selector.selectNow();
selectCnt = 1;
break;
}
}
} catch (CancelledKeyException e) {
// log and continue – harmless JDK bug
}
}Finally, the article summarizes the complete startup sequence: creating EventLoopGroups and a selector, building a channel and its pipeline, setting handlers, registering the channel, binding to the port, and running the event‑loop that selects, rebuilds the selector when necessary, and dispatches read events to the child handler.
Java Captain
Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.