Netty实战:手把手教你实现一个高可用的TCP长连接服务(附完整代码+避坑指南)
视频看了几百小时还迷糊关注我几分钟让你秒懂发点评论可以给博主加热度哦一、为什么用 Netty真实业务场景解析在物联网IoT、金融交易、游戏服务器、即时通讯等场景中高并发、低延迟、稳定可靠的 TCP 长连接是刚需。 场景智能设备上报数据10万台设备通过 TCP 连接服务器每秒上报位置、电量、状态等信息服务器需实时处理并下发指令如“重启”、“升级”传统 Java BIOBlocking IO方案ServerSocket server new ServerSocket(8080); while (true) { Socket socket server.accept(); // 阻塞 new Thread(() - handle(socket)).start(); // 每连接开一线程 }❌ 问题线程数爆炸10万连接 10万线程上下文切换开销大内存耗尽、系统崩溃Netty 方案Reactor 模型✅ 优势单线程可处理数万连接基于 NIO 事件驱动内存池、零拷贝优化性能自带心跳、粘包/拆包、重连等机制二、Spring Boot Netty 快速搭建 TCP 服务正确姿势 注意Netty 是独立于 Spring 的网络框架但可无缝集成到 Spring Boot 项目中。第一步添加依赖pom.xmldependency groupIdio.netty/groupId artifactIdnetty-all/artifactId version4.1.100.Final/version /dependency !-- 可选用于优雅关闭 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency第二步定义消息协议解决粘包/拆包我们采用长度字段 JSON的自定义协议| 4字节长度 | JSON字符串 | |-----------|------------| | 00 00 00 1C | {cmd:login,data:{id:D1001}} |✅ 为什么不用纯文本因为 TCP 是流式协议不保证消息边界必须定义协议第三步编写消息编解码器1. 消息实体类public class TcpMessage { private String cmd; // 指令login, heartbeat, data private Object data; // 负载数据 // getter/setter/toString 略 }2. 编码器Java对象 → 字节流public class MessageEncoder extends MessageToByteEncoderTcpMessage { Override protected void encode(ChannelHandlerContext ctx, TcpMessage msg, ByteBuf out) { try { String json new ObjectMapper().writeValueAsString(msg); byte[] bytes json.getBytes(StandardCharsets.UTF_8); out.writeInt(bytes.length); // 写入4字节长度 out.writeBytes(bytes); // 写入JSON内容 } catch (Exception e) { throw new RuntimeException(编码失败, e); } } }3. 解码器字节流 → Java对象public class MessageDecoder extends LengthFieldBasedFrameDecoder { public MessageDecoder() { super( 1024 * 1024, // maxFrameLength 最大帧长度 0, // lengthFieldOffset 长度字段偏移 4, // lengthFieldLength 长度字段占4字节 0, // lengthAdjustment 4 // initialBytesToStrip 跳过长度字段 ); } Override protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception { ByteBuf frame (ByteBuf) super.decode(ctx, in); if (frame null) return null; try { byte[] bytes new byte[frame.readableBytes()]; frame.readBytes(bytes); String json new String(bytes, StandardCharsets.UTF_8); return new ObjectMapper().readValue(json, TcpMessage.class); } finally { frame.release(); } } }第四步实现业务处理器Component ChannelHandler.Sharable // 标记为可共享避免每次新建 public class TcpServerHandler extends SimpleChannelInboundHandlerTcpMessage { private static final Logger log LoggerFactory.getLogger(TcpServerHandler.class); Override public void channelActive(ChannelHandlerContext ctx) { log.info(设备上线: {}, ctx.channel().remoteAddress()); // 可在此记录连接、分配ID等 } Override public void channelInactive(ChannelHandlerContext ctx) { log.info(设备离线: {}, ctx.channel().remoteAddress()); // 清理资源、标记离线 } Override protected void channelRead0(ChannelHandlerContext ctx, TcpMessage msg) { log.info(收到消息: {}, msg); // 根据指令处理 switch (msg.getCmd()) { case login: handleLogin(ctx, msg); break; case heartbeat: // 心跳直接回复 ctx.writeAndFlush(new TcpMessage(ack, ok)); break; case data: handleData(ctx, msg); break; default: ctx.writeAndFlush(new TcpMessage(error, unknown command)); } } private void handleLogin(ChannelHandlerContext ctx, TcpMessage msg) { // 模拟登录验证 String deviceId ((MapString, String) msg.getData()).get(id); log.info(设备 {} 登录成功, deviceId); ctx.writeAndFlush(new TcpMessage(login_ack, success)); } private void handleData(ChannelHandlerContext ctx, TcpMessage msg) { // 处理业务数据 ctx.writeAndFlush(new TcpMessage(data_ack, received)); } Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { log.error(连接异常: {}, ctx.channel().remoteAddress(), cause); ctx.close(); // 出错关闭连接 } }第五步启动 Netty 服务集成到 Spring BootComponent public class NettyTcpServer { private static final Logger log LoggerFactory.getLogger(NettyTcpServer.class); private EventLoopGroup bossGroup; private EventLoopGroup workerGroup; private Channel serverChannel; Autowired private TcpServerHandler tcpServerHandler; PostConstruct public void start() throws InterruptedException { bossGroup new NioEventLoopGroup(1); workerGroup new NioEventLoopGroup(); ServerBootstrap bootstrap new ServerBootstrap() .group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializerSocketChannel() { Override protected void initChannel(SocketChannel ch) { ch.pipeline() .addLast(new MessageDecoder()) .addLast(new MessageEncoder()) .addLast(tcpServerHandler); // 业务处理器 } }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); serverChannel bootstrap.bind(8080).sync().channel(); log.info(Netty TCP 服务已启动监听端口: 8080); } PreDestroy public void stop() { if (serverChannel ! null) { serverChannel.close(); } if (bossGroup ! null) { bossGroup.shutdownGracefully(); } if (workerGroup ! null) { workerGroup.shutdownGracefully(); } log.info(Netty TCP 服务已关闭); } }✅ 关键点使用PostConstruct启动PreDestroy优雅关闭ChannelHandler.Sharable避免重复创建 Handler 实例三、客户端测试代码模拟设备public class TcpClientTest { public static void main(String[] args) throws Exception { EventLoopGroup group new NioEventLoopGroup(); try { Bootstrap bootstrap new Bootstrap() .group(group) .channel(NioSocketChannel.class) .handler(new ChannelInitializerSocketChannel() { Override protected void initChannel(SocketChannel ch) { ch.pipeline() .addLast(new MessageDecoder()) .addLast(new MessageEncoder()) .addLast(new SimpleChannelInboundHandlerTcpMessage() { Override protected void channelRead0(ChannelHandlerContext ctx, TcpMessage msg) { System.out.println(收到服务端回复: msg); } }); } }); Channel channel bootstrap.connect(localhost, 8080).sync().channel(); // 发送登录 TcpMessage loginMsg new TcpMessage(); loginMsg.setCmd(login); loginMsg.setData(Map.of(id, D1001)); channel.writeAndFlush(loginMsg); // 发送心跳 TcpMessage hb new TcpMessage(); hb.setCmd(heartbeat); hb.setData(ping); channel.writeAndFlush(hb); // 保持连接 Thread.sleep(5000); channel.closeFuture().sync(); } finally { group.shutdownGracefully(); } } }四、常见反例 避坑指南新手必看❌ 反例1未处理粘包/拆包 → 消息解析错乱// 错误直接按行读取只适用于 \n 分隔的文本协议 ch.pipeline().addLast(new LineBasedFrameDecoder(1024));✅ 正确使用LengthFieldBasedFrameDecoder或自定义协议头❌ 反例2Handler 不加Sharable→ 内存泄漏// 每次连接都 new 一个 Handler持有上下文引用无法释放 .childHandler(new ChannelInitializer...() { protected void initChannel(...) { ch.pipeline().addLast(new TcpServerHandler()); // ❌ } });✅ 正确注入 Spring Bean 并标记Sharable❌ 反例3未设置 SO_KEEPALIVE → 僵尸连接堆积// 默认不开启 TCP 心跳断网后连接仍“假在线” .childOption(ChannelOption.SO_KEEPALIVE, false); // ❌✅ 正确.childOption(ChannelOption.SO_KEEPALIVE, true); // 或应用层实现心跳更可靠❌ 反例4异常未关闭连接 → 资源泄露Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // 什么都不做连接会一直挂着 }✅ 正确捕获异常后ctx.close()五、生产环境增强建议功能实现方式心跳检测客户端定时发heartbeat服务端记录最后活跃时间超时踢出连接管理用ConcurrentHashMapString, Channel存储设备ID与Channel映射SSL加密添加SslHandler到 pipeline流量控制使用ChannelOption.WRITE_BUFFER_WATER_MARK监控指标暴露连接数、吞吐量等指标到 Prometheus六、总结Netty 强大但复杂协议设计 代码实现。本文带你✅ 从零搭建 Spring Boot Netty TCP 服务✅ 解决粘包/拆包、连接管理、异常处理等核心问题✅ 避开内存泄漏、僵尸连接等致命陷阱记住高并发不是堆机器而是靠合理架构。Netty 是你构建高性能网络服务的基石视频看了几百小时还迷糊关注我几分钟让你秒懂发点评论可以给博主加热度哦

相关新闻

集成双 5W 功放 + AI 降噪!WX-0813 语音模组让全场景通话体验翻倍

集成双 5W 功放 + AI 降噪!WX-0813 语音模组让全场景通话体验翻倍

在智能设备爆发的当下,语音交互已成为核心需求之一,但环境噪音、通话回音、音频电路复杂等问题却一直困扰着开发者。无论是车载通话的风噪干扰、会议设备的多人回音,还是安防监控的环境杂音,都严重影响语音传输的清晰度。今天给大…

2026/7/3 14:45:30 阅读更多 →
6.3 Istio流量管理实战:实现Bookinfo的灰度发布和A B测试

6.3 Istio流量管理实战:实现Bookinfo的灰度发布和A B测试

6.3 Istio流量管理实战:实现Bookinfo的灰度发布和A/B测试 引言 Bookinfo是学习Istio流量管理的绝佳示例。通过Bookinfo可以实现灰度发布、A/B测试等高级流量管理功能。本文将详细介绍如何使用Istio管理Bookinfo的流量。 一、版本管理 1.1 定义版本 apiVersion: networkin…

2026/7/3 14:45:31 阅读更多 →
写作压力小了,AI论文软件 千笔·专业论文写作工具 VS 万方智搜AI

写作压力小了,AI论文软件 千笔·专业论文写作工具 VS 万方智搜AI

随着人工智能技术的迅猛迭代与普及,AI辅助写作工具已逐步渗透到高校学术写作场景中,成为专科生、本科生、研究生完成毕业论文不可或缺的辅助手段。越来越多面临毕业论文压力的学生,开始依赖各类AI工具简化写作流程、提升创作效率。但与此同时…

2026/7/3 14:45:35 阅读更多 →

最新新闻

MC74HC165A与PIC18LF25K40实现高效数字输入扩展方案

MC74HC165A与PIC18LF25K40实现高效数字输入扩展方案

1. 项目背景与核心价值在嵌入式系统开发中,处理多路数字输入信号是常见需求。传统方案需要为每个输入信号分配独立的GPIO引脚,当系统规模扩大时,这会导致引脚资源紧张、布线复杂和成本上升。MC74HC165A作为8位并行输入/串行输出移位寄存器&am…

2026/7/4 14:44:13 阅读更多 →
PDown:专业级百度网盘下载加速解决方案完全指南

PDown:专业级百度网盘下载加速解决方案完全指南

PDown:专业级百度网盘下载加速解决方案完全指南 【免费下载链接】pdown 百度网盘下载器,2020百度网盘高速下载 项目地址: https://gitcode.com/gh_mirrors/pd/pdown PDown是一款专为解决百度网盘下载速度限制而设计的第三方下载工具,通…

2026/7/4 14:44:13 阅读更多 →
基于深度学习的单目视觉FCW系统实现与优化

基于深度学习的单目视觉FCW系统实现与优化

1. 项目概述:基于深度学习的单目视觉FCW系统 前车碰撞预警系统(Forward Collision Warning,FCW)是智能驾驶辅助系统(ADAS)的核心安全功能之一。与传统的雷达方案相比,基于单目视觉的FCW系统具有…

2026/7/4 14:40:10 阅读更多 →
STM32与EEPROM硬件设计及I2C驱动优化实践

STM32与EEPROM硬件设计及I2C驱动优化实践

1. S-34C04AB与STM32F207VGT6的硬件协同设计 在嵌入式存储系统中,S-34C04AB作为I2C接口的4Kb EEPROM芯片,与STM32F207VGT6的硬件配合需要特别注意电气特性和信号完整性。STM32F207VGT6的I2C接口工作电压为3.3V,而S-34C04AB支持1.7V-5.5V宽电压…

2026/7/4 14:40:10 阅读更多 →
3分钟免费解锁MobaXterm专业版:开源许可证生成器终极指南

3分钟免费解锁MobaXterm专业版:开源许可证生成器终极指南

3分钟免费解锁MobaXterm专业版:开源许可证生成器终极指南 【免费下载链接】MobaXterm-keygen A keygen for MobaXterm 项目地址: https://gitcode.com/gh_mirrors/moba/MobaXterm-keygen 还在为MobaXterm专业版的高昂费用而犹豫吗?想要体验完整的…

2026/7/4 14:36:09 阅读更多 →
Hugging Face Hub大文件上传实战指南

Hugging Face Hub大文件上传实战指南

1. 大文件上传需求背景在机器学习领域,数据集和模型文件往往体积庞大。以常见的计算机视觉数据集为例,一个中等规模的图像数据集可能达到几十GB甚至上百GB。传统的文件托管服务要么有严格的容量限制,要么缺乏版本控制功能,给团队协…

2026/7/4 14:34:07 阅读更多 →

日新闻

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 发布:关键安全修复版本,多项问题得到解决

Memcached 1.6.43 正式发布,这是一个关键的安全修复版本,修复了多个方面的问题,还对部分功能进行了优化。 安全修复亮点 此次发布在安全修复上表现突出。binprot 避免了项目引用计数溢出,mcmc 因安全问题提升了上游版本号&#xf…

2026/7/4 0:04:29 阅读更多 →
终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案

终极指南:使用HMCL启动器跨平台畅玩Minecraft的完整解决方案 【免费下载链接】HMCL A Minecraft Launcher which is multi-functional, cross-platform and popular 项目地址: https://gitcode.com/gh_mirrors/hm/HMCL HMCL(Hello Minecraft! Lau…

2026/7/4 0:06:29 阅读更多 →
KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

KMX63与PIC18F66K40在嵌入式HMI中的硬件协同与低功耗设计

1. KMX63与PIC18F66K40的硬件协同架构解析KMX63作为一款三轴加速度计和磁力计组合传感器,与PIC18F66K40微控制器的搭配堪称嵌入式HMI开发的黄金组合。这套硬件组合的核心优势在于KMX63提供的高精度运动感知能力与PIC18F66K40强大的信号处理能力形成了完美互补。KMX6…

2026/7/4 0:06:29 阅读更多 →

周新闻

月新闻