消息广播场在网络通讯应用还是普遍存在,如游戏中玩家状态通知,聊天和公共消息发送等,但在面对大量业务消息广播的情况可能会面临一些性能上的问题需要处理;毕竟大量业务不仅在消息序列化上非常损耗CPU,在网络IO读写上因过于频繁也会引起大量的损耗,如果没有处理好的情况还是非常影响整全服务性能。
消息广播场景
一般的设计都是把消息先写入会话中,然后会话内部进行消息转化成协议数据最终通过Socket
发送出去。这种设计不好的地方在于业务消息比较复杂,广播的会话数量规模比较大的情况那那整个消息协议数据转换就非常损耗性能!为什么一般这样设计呢,因为这样内部转换协议对Buffer
的控制相对比较容易可控,只需要关心自己会话的消息协转换发送回收即可。
广播应用优化
通过把协议转换前置,然后再把Buffer
转到会话再由Socket
发送出去,这样做的好处非常明显就是在大量广播消息的时候性能非常出色,因为无论广播多少个会话只需要协议转换一次就可以。不过问题也非常明显,由于Buffer
是应用者写入并共享到不同会话中,这样就导致Buffr
不受内部管制,这样框架总体性能就不好控制。
整合优化
实际服务应用中,两种情况都会同时存在,不管谁的重权大小在设计只要倾向一边那框架都很难在性能上发挥着优势,毕竟你无法控制上层的应用所面对的情况和应用者的行为。为了更好的控制着性能,所以在实现这些基础功能组件的时候这两种情况都要有所考虑。
由于转换协议是一样的,可以把协议转换抽象出来,然后在发送消息的时候进行一个阀值判断;当超过阀值的时候就先转换消息然后再把buffer
写入到会话中,如果没超过就由会话内部通过转换器处理buffer
.这样在通讯中的buffer
就可以管控起来,不过对于后者来说由于buffer
可以进行共享发送,那在管理上就比较麻烦可以通过发送完成计数来处理;不过由于网络的不可控制这种控制非常困难(最简单的方法是内存块复制到单独的会话buffer
中后回到池中,对于c#这些来说个人建议直接放弃对这一块的管理,毕竟在大量广播下已经降低了很多协议转换的开销)。
Socket写入数据层面的优化
对于C#语言来说Socket的Send方法还是比较损耗性能的,如果每秒要向1000个连接广播10条消息,在正常设计的情况那就意味着触发10000次的Socket的Send操作。虽然这个数量在现有的硬件资源来说并不会存在什么压力,但如果10000个连接或发送的密度更大呢?如果把这方面的损耗压减下来,留给业务处理那不是一件更好的事情!
在会话内部引用一个消息队列,发送的消息先写入队列,然后通过批量的方式把多个消息写入Buffer
中,在发送完成后继续监测队列;发送完成和消息进入会话队列时会存在一个状冲突的过程,需要处理好之间的状态确保队列消息转换的一致性即可(使用定时器方式批量写入发送延时不好控制,特别是会话量比较大的情况下,不建议使用)。通过合并发送在大量小消息的情况下可以达到更高的带宽利用率和低IO读写量,从而让整体性能更出色。
小编结语:其实,针对于通讯行业来说,我们所认识的设计可能运用的不多,但是,现在却会常常使用到的,那么我们也应该好好学习一下设计了。
来源于:泥水佬
大数据+Python网络爬虫实战项目视频教程,共7节视频教程,随时随地学习,24小时内讲师答疑,与万千学友在线讨论。
课程网址:http://www.kokojia.com/course-4353.html?invite_id=10052883
版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出处、作者信息和本声明,否则将追究法律责任。https://blog.kokojia.com/love15200922/b-1950.html