Spring 中 Netty 的应用完全指南
基于 Spring Boot 3.x + Netty 4.1.x 的 服务端、客户端、WebFlux、WebSocket 四合一实践 含 完整源码、生命周期、线程模型、自动配置 解析
目录
- 背景:为什么要在 Spring 里用 Netty
- 整体架构
- 场景一:内嵌 Netty 作为 Web 容器
- 场景二:自定义 TCP/UDP 服务器
- 场景三:WebSocket 长连接
- Spring Boot 自动装配源码走读
- 生命周期与线程模型
- 最佳实践与性能调优
- 常见问题 FAQ
- 总结
背景
- Tomcat/Jetty 是阻塞式 Servlet 容器,高并发场景下线程消耗大。
- Netty 采用 NIO + 事件驱动 ,单线程可支撑 万级连接。
- Spring Boot 3.x 官方支持 WebFlux 与 Reactor Netty,整合更丝滑。
整体架构

场景一:内嵌 Netty 作为 Web 容器(WebFlux)
1. 引入依赖
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
spring-boot-starter-webflux
默认使用 Reactor Netty(Netty 的响应式封装)。
2. 自定义配置(可选)
typescript
@Configuration
public class NettyWebFluxConfig implements WebServerFactoryCustomizer<NettyReactiveWebServerFactory> {
@Override
public void customize(NettyReactiveWebServerFactory factory) {
factory.addServerCustomizers(httpServer ->
httpServer
.port(9000)
.option(ChannelOption.SO_BACKLOG, 1024)
.childOption(ChannelOption.TCP_NODELAY, true)
);
}
}
3. 路由示例
typescript
@SpringBootApplication
public class WebFluxApplication {
public static void main(String[] args) {
SpringApplication.run(WebfluxApplication.class, args);
}
@Bean
public RouterFunction<ServerResponse> route() {
return RouterFunctions
.route(GET("/hello"), req -> ServerResponse.ok().bodyValue("Hello Netty"));
}
}
访问 http://localhost:9000/hello
即可返回 Hello Netty
。
场景二:自定义 TCP/UDP 服务器
1. Maven 依赖
xml
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.110.Final</version>
</dependency>
2. 启动器(跟随 Spring 生命周期)
typescript
@Component
public class TcpServer implements SmartLifecycle {
private final EventLoopGroup boss = new NioEventLoopGroup(1);
private final EventLoopGroup worker = new NioEventLoopGroup(0);
private Channel channel;
@Override
public void start() {
try {
ServerBootstrap bootstrap = new ServerBootstrap()
.group(boss, worker)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
p.addLast(new StringDecoder());
p.addLast(new StringEncoder());
p.addLast(new SimpleChannelInboundHandler<String>() {
@Autowired
private EchoService service; // Spring 注入
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) {
ctx.writeAndFlush(service.echo(msg));
}
});
}
});
channel = bootstrap.bind(8888).sync().channel();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
@Override
public void stop() {
if (channel != null) channel.close();
boss.shutdownGracefully();
worker.shutdownGracefully();
}
@Override
public boolean isRunning() {
return channel != null && channel.isActive();
}
}
3. 业务 Service
typescript
@Service
public class EchoService {
public String echo(String msg) {
return "Echo: " + msg;
}
}
场景三:WebSocket 长连接
java
@Component
public class WebSocketServer implements SmartLifecycle {
@Override
public void start() throws Exception {
ServerBootstrap bootstrap = new ServerBootstrap()
.group(new NioEventLoopGroup(1), new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline()
.addLast(new HttpServerCodec())
.addLast(new HttpObjectAggregator(65536))
.addLast(new WebSocketServerProtocolHandler("/ws"))
.addLast(new SimpleChannelInboundHandler<TextWebSocketFrame>() {
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) {
ctx.writeAndFlush(new TextWebSocketFrame("Received: " + frame.text()));
}
});
}
});
bootstrap.bind(9999).sync();
}
}
客户端连接 ws://localhost:9999/ws
即可实时通信。
Spring Boot 自动装配源码走读
1. 入口:ReactorNettyAutoConfiguration
less
@AutoConfiguration
@ConditionalOnClass(HttpServer.class)
@EnableConfigurationProperties(ServerProperties.class)
public class ReactorNettyAutoConfiguration {
@Bean
public NettyReactiveWebServerFactory nettyReactiveWebServerFactory() {
return new NettyReactiveWebServerFactory();
}
}
2. 工厂创建 ServerBootstrap
scala
public class NettyReactiveWebServerFactory extends AbstractReactiveWebServerFactory {
@Override
public WebServer getWebServer(HttpHandler httpHandler) {
return new NettyWebServer(
HttpServer.create()
.port(getPort())
.handle(new ReactorHttpHandlerAdapter(httpHandler))
);
}
}
生命周期与线程模型
阶段 | 线程 | 说明 |
---|---|---|
启动 | 主线程 | Spring Boot SmartLifecycle |
Accept | Boss EventLoop | 单线程处理连接事件 |
I/O | Worker EventLoop | 多线程处理读写 |
业务 | Worker 或自定义线程池 | 耗时任务外移 |
最佳实践
建议 | 配置 |
---|---|
线程数 | Boss=1,Worker=CPU*2 |
ChannelOption | SO_BACKLOG=1024 , TCP_NODELAY=true |
ChannelHandler | 使用 @Sharable 保证单例 |
内存 | ByteBuf.release() 避免泄漏 |
常见问题 FAQ
问题 | 解决 |
---|---|
端口冲突 | server.port 与 netty.port 分离 |
Handler 非 Spring Bean | 使用 @Component + @Autowired |
优雅关闭 | EventLoopGroup.shutdownGracefully() |
总结
- Spring Boot + Netty = 阻塞逻辑 与 非阻塞 I/O 的完美结合
- WebFlux 内置,自定义 TCP/UDP/WebSocket 三行代码即可
- 掌握 生命周期、线程模型、ChannelOption ,即可构建 万级并发 的 Spring 应用!