|
|
# 优化改进总结
|
|
|
|
|
|
## 已完成的优化(高优先级)
|
|
|
|
|
|
### 1. ✅ 添加Unpacker Buffer大小限制(防止内存耗尽)
|
|
|
|
|
|
**实现内容**:
|
|
|
- 在所有Unpacker实现中添加了`MaxBufferSize`配置项
|
|
|
- 默认最大buffer大小为10MB(`DefaultMaxBufferSize`)
|
|
|
- 在`Unpack`方法中添加了buffer大小检查
|
|
|
- 添加了长度字段验证,防止恶意数据导致内存耗尽
|
|
|
- 优化了buffer的内存分配策略(预分配容量,减少重新分配)
|
|
|
|
|
|
**涉及文件**:
|
|
|
- `pkg/unpacker/unpacker.go` - 添加了`MaxBufferSize`字段和默认常量
|
|
|
- `internal/unpacker/length_field.go` - 实现了大小限制和验证
|
|
|
- `internal/unpacker/fixed_length.go` - 实现了大小限制
|
|
|
- `internal/unpacker/delimiter.go` - 实现了大小限制
|
|
|
- `internal/unpacker/frame_header.go` - 实现了大小限制
|
|
|
|
|
|
### 2. ✅ 使用Conn.Context()存储连接数据(提高性能)
|
|
|
|
|
|
**实现内容**:
|
|
|
- 创建了`connectionData`结构体,存储连接、unpacker和protocol
|
|
|
- 在`OnOpen`时将连接数据存储到`gnet.Conn.Context()`
|
|
|
- 在`OnTraffic`中直接从Context获取连接数据,避免查找
|
|
|
- 在`OnClose`时清理Context
|
|
|
|
|
|
**涉及文件**:
|
|
|
- `internal/server/connection_data.go` - 新增文件,实现Context管理
|
|
|
- `internal/server/server.go` - 修改OnOpen、OnTraffic、OnClose方法
|
|
|
|
|
|
**性能提升**:
|
|
|
- 避免了每次数据到达时的连接查找操作
|
|
|
- 减少了锁竞争
|
|
|
- 提高了数据访问速度
|
|
|
|
|
|
### 3. ✅ 使用AsyncWrite异步写入(避免阻塞)
|
|
|
|
|
|
**实现内容**:
|
|
|
- 修改`Connection.Write`方法,使用`AsyncWrite`替代同步`Write`
|
|
|
- 在异步写入前复制数据,避免数据被修改
|
|
|
- 添加了写入错误回调处理
|
|
|
|
|
|
**涉及文件**:
|
|
|
- `internal/connection/connection.go` - 修改Write方法
|
|
|
|
|
|
**性能提升**:
|
|
|
- 避免阻塞事件循环
|
|
|
- 提高并发写入性能
|
|
|
- 更好的资源利用
|
|
|
|
|
|
### 4. ✅ 改进错误处理(提高稳定性)
|
|
|
|
|
|
**实现内容**:
|
|
|
- 创建了错误分类系统(可恢复、不可恢复、致命错误)
|
|
|
- 实现了`classifyError`函数,根据错误类型进行分类
|
|
|
- 实现了`handleError`方法,统一处理错误
|
|
|
- 实现了`formatError`函数,格式化错误信息(包含上下文)
|
|
|
- 在关键位置使用改进的错误处理
|
|
|
|
|
|
**涉及文件**:
|
|
|
- `internal/server/error_handler.go` - 新增文件,实现错误处理逻辑
|
|
|
- `internal/server/server.go` - 在Unpack、parseRequestBody、handler等位置使用改进的错误处理
|
|
|
|
|
|
**改进效果**:
|
|
|
- 更细粒度的错误处理
|
|
|
- 更好的错误上下文信息
|
|
|
- 自动判断是否需要关闭连接
|
|
|
- 提高系统稳定性
|
|
|
|
|
|
### 5. ✅ 添加对象池(减少GC压力)
|
|
|
|
|
|
**实现内容**:
|
|
|
- 创建了`messagePool`用于复用消息缓冲区
|
|
|
- 创建了`messagesPool`用于复用消息列表
|
|
|
- 实现了`getMessageBuffer`和`putMessageBuffer`方法
|
|
|
- 实现了`getMessagesSlice`和`putMessagesSlice`方法
|
|
|
- 添加了容量限制,避免池中积累大对象
|
|
|
|
|
|
**涉及文件**:
|
|
|
- `internal/server/pool.go` - 新增文件,实现对象池
|
|
|
- `internal/request/request.go` - 添加了`Reset`方法
|
|
|
- `internal/response/response.go` - 添加了`Reset`方法
|
|
|
|
|
|
**注意**:Request和Response的对象池暂时未完全集成,因为它们需要特定的初始化参数。可以在后续优化中进一步完善。
|
|
|
|
|
|
### 6. ✅ 优化Unpacker Buffer内存分配
|
|
|
|
|
|
**实现内容**:
|
|
|
- 在创建Unpacker时预分配初始容量
|
|
|
- 在`Unpack`方法中,如果容量不足,智能扩容(2倍增长,但不超过maxBufferSize)
|
|
|
- 减少了频繁的内存重新分配
|
|
|
|
|
|
**涉及文件**:
|
|
|
- `internal/unpacker/length_field.go`
|
|
|
- `internal/unpacker/fixed_length.go`
|
|
|
- `internal/unpacker/delimiter.go`
|
|
|
- `internal/unpacker/frame_header.go`
|
|
|
|
|
|
## 待完成的优化(中低优先级)
|
|
|
|
|
|
### 7. ⏳ 优化连接管理器(减少锁竞争)
|
|
|
|
|
|
**建议实现**:
|
|
|
- 使用分段锁(sharded locks)替代全局锁
|
|
|
- 或使用读写锁优化读操作
|
|
|
- 考虑使用sync.Map(如果适用)
|
|
|
|
|
|
### 8. ⏳ 添加超时控制(防止资源泄漏)
|
|
|
|
|
|
**建议实现**:
|
|
|
- 为每个消息处理设置超时
|
|
|
- 使用`context.WithTimeout`控制处理时间
|
|
|
- 超时后自动取消处理
|
|
|
|
|
|
### 9. ⏳ 实现优雅关闭(提高可用性)
|
|
|
|
|
|
**建议实现**:
|
|
|
- 停止接受新连接
|
|
|
- 等待正在处理的请求完成
|
|
|
- 设置关闭超时
|
|
|
- 清理资源
|
|
|
|
|
|
### 10. ⏳ 减少内存拷贝(零拷贝优化)
|
|
|
|
|
|
**建议实现**:
|
|
|
- 尽量减少不必要的内存拷贝
|
|
|
- 使用零拷贝技术(如果可能)
|
|
|
- 复用缓冲区
|
|
|
|
|
|
## 性能改进预期
|
|
|
|
|
|
1. **内存使用**:通过buffer大小限制和对象池,预计减少20-30%的内存使用
|
|
|
2. **CPU使用**:通过Conn.Context()和AsyncWrite,预计减少10-15%的CPU使用
|
|
|
3. **吞吐量**:通过异步写入和优化错误处理,预计提升15-25%的吞吐量
|
|
|
4. **稳定性**:通过改进的错误处理和资源限制,显著提高系统稳定性
|
|
|
|
|
|
## 后续建议
|
|
|
|
|
|
1. **性能测试**:进行压力测试,验证优化效果
|
|
|
2. **监控指标**:添加更多性能监控指标
|
|
|
3. **文档完善**:更新使用文档,说明新的配置选项
|
|
|
4. **示例代码**:提供优化后的使用示例
|
|
|
|