简述
一年过去,忙碌而多烦忧,多在管理和处理线上故障上,能沉下心写代码的时间少,所以开源就更顾不上了,间隔或修改一二,但都无闲暇做完整测试,也无更新。
近来,有些空余,也因一项目需要,把通信框架修改了不少,昨天发布,现做简单的阐述。
本次版本姑且称Version 0.7吧,于我心中,还缺不少模块,也缺一些功能,离大规模高质量传输还有些距离,虽然已经不错(得自夸下^_^),但离对实时性和延迟要求高的场景,还需要多应用和改进,框架已经搭建起来了,但是细节性能的优化,那所涉甚多,得慢慢调优。
对于功能和模块,还缺少很多东西,比如P2P,比如通信网关转发,比如像protocol buf一样的便捷配置工具和包对象测试框架,前路慢慢。
对于便捷实用,还需要不少时间去增加,比如框架的参数配置和热加载,比如使用说明,比如快速配置RPC对象等等,来日方长啊。
源码地址
GitHub:https://github.com/KonsanAlide/KonsanNet
更新内容
CXCommon
包结构修改
修改了包结构,在CXPacketBodyData中增加了RPC对象的GUID和包的GUID,RPC对象的GUID用于访问PRC对象时产生、访问、销毁一种RPC对象,包的GUID就是用于标识从该请求发起到最终反馈回到发起方的整个链路的会话ID,用于分析追踪和定位请求在传输处理中发生的问题。为了更方便快速的解决使用中遇到的问题,只能牺牲点带宽和性能,两个GUID总增加了32个字节,也就是v0.7后,每个消息包比以前增加32个字节长度。
如有同学在实际使用中,为了带宽考虑,无需使用RPC也无需使用包GUID,依然希望使用以前的通过包编码来通信的方式,可以修改如下:
- 修改CXCommon/include/CXCommonPacketStructure.h文件中的CXPacketBodyData定义,把byObjectGuid和byPacketGuid两个数组去除。
- 然后把CXCommunicationClient和CXCommunicationServer里面使用到byObjectGuid和byObjectGuid的地方的逻辑进行修改,主要是CXMessageProcessLevelBase::ProcessMessage()函数,可以参考V0.61版本的代码来修改,以及修改CXTcpClient::SendPacket函数,把两个GUID去除。
增加RPC对象映射定义
在CXCommon/include/CXPacketCodeDefine.h中增加了const map<string, string> g_mapRPCObjectGuid,用于标识RPC对象的名称和GUID的映射,后面版本会修改成管理库。
新同学构建自己的RPC对象的过程中需要把对象的名称和GUID填写到该map中,用于程序内部根据该map来创建对应的RPC对象。
增加GUID的简单封装类
在CXCommon中增加了CXGuidObject,用于对windows和linux的guid进行简单的封装,用于便捷实用。
CXCommunicationClient
RPC对象功能
增加了RPC对象的客户端基类CXRPCObjectClient,用于统一RPC对象的基本函数和隐藏底层通信接口,以便继承使用。
Bug修正
- 修正了CXFileTcpClient::Write函数中使用了CXTcpClient的发送缓冲来直接写入数据(为了减少一次内存复制)产生的缓冲地址和长度计算出错的问题。
- 在CXFileTcpClient::Write函数中增加seek位置和方向参数,对于文件写入,如果写入之前需要重新定位,那么无需再调用一次CXFileTcpClient::Seek函数,直接用CXFileTcpClient::Write函数可以一次完成寻位并写入的功能(服务端CXFileRPCServer对象支持该功能处理)。
- 补漏CXTcpClient的析构函数未关闭通信、清理缓存指针和释放内存的问题。
CXCommunicationServer
RPC对象功能
增加了RPC对象的服务端基类CXRPCObjectServer,用于统一RPC对象的基本函数和隐藏底层通信接口,以便继承使用。修改CXMessageProcessLevelBase::ProcessMessage()的处理逻辑,从原来根据包号码来进行分派消息包并处理的逻辑改成根据RPC对象GUID来调用RPC对象的方法进行处理。
拆包优化
优化了CXConnectionObject::RecvPacket函数中拆包处理过程,简化了一些逻辑。
连接管理
在CXConnectionsManager中增加连接超时管理,如果长时间没有收到心消息包或者心跳包,那么服务端会把该连接关闭,目前超时时间通过CXConnectionObject::m_dwTimeOutMSeconds属性来修改,后期版本会增加通过外部的配置文件来进行配置。
在CXConnectionsManager中增加连接关闭后对象延迟回收功能,在CXConnectionsManager::DetectConnections()中实现,实现当一个连接已经被完全关闭2000毫秒后会被增加到复用队列m_queueFreeConnections中,以便新接收的连接使用。
会话管理
简少CXSessionsManager中的锁,简化会话关闭和回收逻辑。
解密和解压线程缓存管理
为了更高效高速的使用内存,在CXSocketServerKernel::WaitThread()中增加了一个10MB缓存(消息包最大只能为10MB),用于消息包的解密和解压,无需在消息包的解密和解压时再动态从缓存池里面申请新内存。
引入C++11的chrono时间库
引入C++11的chrono时间库用于计算毫秒和纳秒级别的时间戳和间隔,也就是以后CXCommunicationServer工程必须使用C++11,如在低版本的Linux系统下编译,需要升级gcc和g++版本。
增加请求耗时输出
引入Journal log,在CXMessageProcessLevelBase::ProcessMessage()中增加请求处理耗时输出,后期版本会在journal日志里面增加更像详细的包内容格式化输出。
Bug修正
- 修正连接和会话关闭时的一些bug,让会话和连接对象可以再次安全复用。
- 修正Linux平台CXConnectionObject::SendData发送数据时遇到EAGAIN时处理出错的问题。
- 去除几个多余的类对象。
CXEvent
Bug修正
- 修正了CXEvent::WaitForSingleObject中Linux下计时单位出错导致等待时长不对的问题。
CXFile
Bug修正
- 修正了CXFile64::Open函数中打开已经存在的设备写入的报错问题。
- 修正了CXFile64::Seek中获取设备的大小出错导致Seek出错的问题。
- 修正了CXFile64::Close() linux下漏掉return和复位m_file和m_bIsOpened的问题。
CXMemoryCache
增加内存池的弹性伸缩
增加一个CXElasticMemoryCache类来实现一种大小的内存池的伸缩机制,CXMemoryCacheManager里面来增加线程进行闲时内存池回收。
修改优化内存池管理性能
修改CXMemoryCacheManager中内存池的管理,使内存申请和释放更快速。
CXLog
修改日志写入线程立刻刷盘为定期刷盘
原来的日志写入的线程,当写入一条日志到文件的时候,直接flush,现在改成1秒钟flush一次。
输出毫秒级日志时间
在Log()函数里面增加毫秒时间的输出,以更精确的定位日志产生时间。
CXThread
Bug修复
修正CXThread::Start()中m_pThreadPara = pThreadPara在线程创建之后,导致指针引用报错问题。
其它
后面短期内的版本会增加如下功能:
- RPC对象的消息处理后把消息格式化输出到journal 日志
- 增加CXConnectionObject发送队列和发送线程,把windows的socket改成异步通信。
- 增加转发到第三方的逻辑,创建新的socket,产生CXConnectionObject并增加到epoll和iocp发送接收数据。
- 增加数据发送到第三方后,返回时的消息处理。
- 增加服务端的各模块参数外部配置和热加载
- 增加像protocol buf那样的便捷的产生包结构和测试的库。
- 选择合适的加密算法和压缩算法增加加解密和压缩解压处理。
- 增加消息处理耗时统计。
- 增加消息处理超时处理。