一、系统架构设计
1.1 整体架构图
+------------------+ WebSocket (wss) +------------------+ Netty TCP +------------------+
| Vue前端 | <-------------------------> | SpringBoot网关 | <------------------> | Netty服务集群 |
| (WebSocket客户端)| 消息加密/心跳 | (WebSocket适配层) | 长连接 | (业务逻辑处理) |
+------------------+ 心跳检测 +------------------+ 管理 +------------------+
↓
+------------------+
| Redis集群 |
| (在线状态同步) |
+------------------+
1.2 技术选型解析
• SpringBoot:提供REST API网关、用户认证、消息路由
• Netty:核心通信框架,处理10W+级长连接,支持自定义协议
• Vue:实现实时消息推送的SPA前端,使用WebSocket API通信
• Redis:存储在线状态、离线消息、分布式Session
• Protobuf:二进制序列化协议,提升传输效率
二、核心原理剖析
2.1 WebSocket协议优势
• 双向全双工通信,避免了HTTP轮询的开销
• 减少TCP连接次数,建立一次连接即可持续通信
• 支持文本/二进制数据传输,适合JSON/Protobuf格式
2.2 Netty高性能架构
线程模型
+------------------+ +------------------+ +------------------+
| BossGroup | | WorkerGroup | | SubReactor |
| (Acceptor线程) | <---> | (I/O处理线程) | <---> | (业务处理线程) |
+------------------+ +------------------+ +------------------+
• BossGroup:处理TCP三次握手,建立连接
• WorkerGroup:处理Channel读写事件
• SubReactor:多线程处理业务逻辑,避免阻塞
关键组件
• ChannelPipeline:消息处理流水线,包含编解码器、业务处理器
• EventLoop:单线程处理多个Channel,保证IO操作的原子性
• MemoryManager:内存池化技术,减少GC压力
三、实战开发指南
3.1 后端实现(SpringBoot + Netty)
3.1.1 依赖配置
<dependency>
<groupId>io.nettygroupId>
<artifactId>netty-allartifactId>
<version>4.1.86.Finalversion>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-websocketartifactId>
dependency>
3.1.2 Netty服务端核心代码
public class ChatServer {
private final int port;
public ChatServer(int port) {
this.port = port;
}
public void run() throws InterruptedException {
EventLoopGroup bossGroup = new NioEventLoopGroup(2);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ch.pipeline()
.addLast(new HttpServerCodec()) // HTTP编解码
.addLast(new HttpObjectAggregator(65536)) // HTTP聚合
.addLast(new WebSocketServerProtocolHandler("/ws")) // WebSocket协议升级
.addLast(new ProtobufDecoder(ChatMessage.getDefaultInstance())) // Protobuf解码
.addLast(new ChatServerHandler()); // 自定义业务处理器
}
});
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
3.1.3 消息处理器实现
public class ChatServerHandler extends SimpleChannelInboundHandler<ChatMessage> {
private static final AttributeKey<String> USER_ID = AttributeKey.valueOf("userId");
@Override
protected void channelRead0(ChannelHandlerContext ctx, ChatMessage msg) {
String userId = ctx.channel().attr(USER_ID).get();
RedisUtils.setOnlineStatus(userId, ctx.channel());
// 消息路由:广播给所有在线用户
broadcastMessage(msg);
}
private void broadcastMessage(ChatMessage message) {
ChannelGroup channels = ChatServer.getChannelGroup();
channels.writeAndFlush(message)
.addListener(future -> {
if (!future.isSuccess()) {
System.err.println("消息发送失败: " + future.cause());
}
});
}
}
3.2 前端实现(Vue3 + WebSocket)
3.2.1 WebSocket连接管理
// src/utils/websocket.js
class WebSocketClient {
constructor(url) {
this.url = url;
this.ws = null;
this.reconnectTimer = null;
}
connect() {
return new Promise((resolve, reject) => {
this.ws = new WebSocket(this.url);
this.ws.onopen = () => {
console.log('WebSocket连接成功');
resolve();
};
this.ws.onmessage = (event) => {
const message = JSON.parse(event.data);
this.handleMessage(message);
};
this.ws.onclose = () => {
console.log('连接关闭,尝试重连...');
this.reconnect();
};
});
}
reconnect() {
this.reconnectTimer = setInterval(() => {
console.log('尝试重新连接...');
this.connect().catch(err => console.error(err));
}, 5000);
}
}
3.2.2 Vue组件集成
四、性能测试报告
4.1 测试环境
组件 | 配置 |
---|---|
服务器 | 4核8G CentOS 7.9 |
Netty版本 | 4.1.86.Final |
并发用户数 | 50,000 |
消息大小 | 1KB JSON |
测试工具 | JMeter 5.6 + WebSocketSampler |
4.2 测试结果
指标 | 数值 |
---|---|
最大连接数 | 85,000+ |
吞吐量 (msg/s) | 122,300 |
平均延迟 | 38ms |
CPU利用率峰值 | 68% |
内存消耗 | 1.2GB/10万连接 |
4.3 性能优化措施
五、扩展功能实现
5.1 消息可靠性保证
// 消息持久化到MySQL
@Async
public void saveMessage(ChatMessage message) {
chatMessageRepository.save(message);
}
// 离线消息存储到Redis
public void storeOfflineMessage(String userId, ChatMessage message) {
redisTemplate.opsForList().rightPush(
"offline:"+userId,
JSON.toJSONString(message)
);
}
5.2 安全增强
// SSL/TLS配置
SslContext sslContext = SslContextBuilder.forServer(
new File("server.crt"),
new File("server.key")
).build();
// 消息鉴权拦截器
public class AuthHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) {
if (!validateToken(ctx)) {
ctx.close();
}
}
}
六、总结与展望
本文实现的系统在5万并发下仍能保持亚秒级响应,验证了Netty在高并发场景下的可靠性。未来可扩展方向: