Netty实战应用学习笔记-中级拓展篇(一)

Netty实战应用学习笔记 - 中级拓展篇

参考博客:bugstack虫洞栈
代码来源:https://github.com/fuzhengwei/itstack-demo-netty
系列:Netty从入门到实战

📚 前言

本文是我学习Netty实战应用的总结笔记,涵盖了13个实战项目。

学习路线图

基础整合篇:
项目2-01:SpringBoot + Netty 整合基础
    ↓
序列化技术篇:
项目2-02:Protobuf 高性能序列化
    ↓
项目2-03:Java对象传输(Protostuff)
    ↓
文件传输篇:
项目2-04:文件传输、分片发送、断点续传
    ↓
实时通信篇:
项目2-05:WebSocket 实时聊天系统
    ↓
数据存储篇:
项目2-06:日志收集系统(Netty + Elasticsearch)
    ↓
RPC基础篇:
项目2-07:请求响应同步通信(RPC基础)
    ↓
连接保活篇:
项目2-08:心跳服务与断线重连
    ↓
集群通信篇:
项目2-09:集群部署实现跨服务端通信
    ↓
协议设计篇:
项目2-10:多种协议消息类型通信处理
    ↓
流量控制篇:
项目2-11:ChunkedStream数据流切块传输
    ↓
项目2-12:流量整形数据流速率控制
    ↓
安全通信篇:
项目2-13:SSL双向加密验证

技术栈总览

技术版本用途
JDK1.8+基础环境
Netty4.1.36.Final网络通信框架
SpringBoot2.0.4应用框架
Protobuf3.5.0二进制序列化
Protostuff1.0.10Java对象序列化
Elasticsearch6.2.2搜索引擎
Redis5.0+消息中间件

为什么要学习这些项目?

在企业级应用开发中,我们会遇到各种实际问题:

问题1:如何将Netty集成到Spring Boot项目中?
→ 项目2-01 解决:SpringBoot整合Netty,实现统一管理

问题2:如何高效传输数据,减少网络开销?
→ 项目2-02/2-03 解决:使用Protobuf/Protostuff序列化,体积减少3-10倍

问题3:如何传输大文件,支持断点续传?
→ 项目2-04 解决:分片传输+断点续传,像网盘一样可靠

问题4:如何实现浏览器与服务器的实时双向通信?
→ 项目2-05 解决:WebSocket协议,实现在线聊天

问题5:如何收集分布式系统的日志并快速检索?
→ 项目2-06 解决:Netty收集+Elasticsearch存储,构建日志系统

问题6:如何实现像HTTP一样的同步调用?
→ 项目2-07 解决:Future模式,异步转同步,RPC框架基础

问题7:如何保持长连接不断开,断开后自动重连?
→ 项目2-08 解决:心跳检测+自动重连,像微信一样稳定

问题8:集群部署时,不同服务器的用户如何通信?
→ 项目2-09 解决:Redis Pub/Sub,实现跨服务器消息传递

问题9:如何优雅地处理多种消息类型?
→ 项目2-10 解决:策略模式+工厂模式,符合开闭原则

问题10:如何传输大数据流,避免内存溢出?
→ 项目2-11 解决:ChunkedStream分块传输,像视频流一样流畅

问题11:如何限制传输速率,避免带宽被占满?
→ 项目2-12 解决:流量整形,像某盘限速一样精准控制

问题12:如何保证通信安全,防止数据被窃取?
→ 项目2-13 解决:SSL/TLS加密,像HTTPS一样安全


🎯 项目一:SpringBoot + Netty 整合基础

项目概述

项目名称:itstack-demo-netty-2-01
核心功能:实现SpringBoot与Netty的整合,提供HTTP和TCP双协议支持
技术要点:CommandLineRunner、编解码器、粘包/半包处理

为什么需要这个项目?

实际问题

  • 单独使用Netty需要手动管理生命周期(启动、关闭)
  • 配置硬编码在代码中,不便于维护
  • 无法使用Spring的依赖注入和AOP等特性
  • 缺少HTTP接口来监控Netty服务器状态

解决方案

  • ✅ 使用SpringBoot管理Netty生命周期
  • ✅ 配置外部化到application.yml
  • ✅ 支持依赖注入,方便集成其他服务
  • ✅ 提供HTTP接口监控Netty状态

适用场景

  • 需要同时提供HTTP和TCP服务的系统
  • 需要监控Netty服务器状态的应用
  • 企业级项目(需要统一的配置管理)
  • 微服务架构(需要与Spring Cloud集成)

核心知识点

1. SpringBoot启动Netty服务器

NettyApplication.java

@SpringBootApplication
public class NettyApplication implements CommandLineRunner {
    
    @Value("${netty.host}")
    private String host;
    @Value("${netty.port}")
    private int port;
    @Autowired
    private NettyServer nettyServer;
    
    @Override
    public void run(String... args) throws Exception {
        // SpringBoot启动完成后自动启动Netty
        InetSocketAddress address = new InetSocketAddress(host, port);
        ChannelFuture channelFuture = nettyServer.bing(address);
        
        // 注册关闭钩子
        Runtime.getRuntime().addShutdownHook(
            new Thread(() -> nettyServer.destroy())
        );
        
        // 阻塞等待服务器关闭
        channelFuture.channel().closeFuture().syncUninterruptibly();
    }
}

关键点

  • CommandLineRunner:SpringBoot启动完成后执行
  • addShutdownHook:优雅关闭Netty服务器
  • syncUninterruptibly():阻塞主线程,保持服务运行
2. Pipeline编解码配置

MyChannelInitializer.java

public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    protected void initChannel(SocketChannel channel) {
        // 1. 基于换行符的帧解码器(解决粘包/半包)
        channel.pipeline().addLast(new LineBasedFrameDecoder(1024));
        
        // 2. 字符串解码器
        channel.pipeline().addLast(new StringDecoder(Charset.forName("GBK")));
        
        // 3. 字符串编码器
        channel.pipeline().addLast(new StringEncoder(Charset.forName("GBK")));
        
        // 4. 业务处理器
        channel.pipeline().addLast(new MyServerHandler());
    }
}

Pipeline处理链

接收数据流程:
字节流 → LineBasedFrameDecoder → StringDecoder → MyServerHandler

发送数据流程:
String → StringEncoder → 字节流 → 网络
3. 粘包/半包问题

什么是粘包/半包?

粘包:多条消息粘在一起
发送:[消息1][消息2][消息3]
接收:[消息1消息2消息3]

半包:一条消息被拆分
发送:[消息1]
接收:[消息1的前半部分] [消息1的后半部分]

解决方案

  • LineBasedFrameDecoder:基于换行符分割
  • FixedLengthFrameDecoder:固定长度分割
  • LengthFieldBasedFrameDecoder:基于长度字段分割
4. HTTP接口监控Netty状态

NettyController.java

@RestController
@RequestMapping("/nettyserver")
public class NettyController {
    
    @Resource
    private NettyServer nettyServer;
    
    @RequestMapping("/localAddress")
    public String localAddress() {
        return "nettyServer localAddress " + 
               nettyServer.getChannel().localAddress();
    }
    
    @RequestMapping("/isOpen")
    public String isOpen() {
        return "nettyServer isOpen " + 
               nettyServer.getChannel().isOpen();
    }
}

项目总结

优点

  • ✅ SpringBoot管理Netty生命周期
  • ✅ 配置外部化(application.yml)
  • ✅ 提供HTTP接口监控
  • ✅ 解决粘包/半包问题

适用场景

  • 需要同时提供HTTP和TCP服务
  • 需要监控Netty服务器状态
  • 简单的文本消息通信

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值