通讯中大量消息广播的设计和优化
消息广播场在网络通讯应用还是普遍存在,如游戏中玩家状态通知,聊天和公共消息发送等,但在面对大量业务消息广播的情况可能会面临一些性能上的问题需要处理;毕竟大量业务不仅在消息序列化上非常损耗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读写量,从而让整体性能更出色。
![](/img/my/wx.png)
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
C++开发EOS基础指南之类与结构
上一篇C++开发EOS的文章是C++开发EOS基础指南:函数参数传递,C++是一种面向对象的编程语言。它有一个强大的继承系统,私有和公共成员变量,以及通过成员初始化列表在构造函数中初始化它们的好方法。析构函数是构造函数的附件,允许你在对象被销毁或超出范围时运行代码。今天让我们创建一个简单的CryptoCurrency类,另外看看继承。 // @url: https://repl.it/@MrToph/CPPBasics-Classes-1 #include <iostream> #include <string> #include <stdlib.h> //自动解析std命名空间,所以我们可以写字符串而不是std::string using namespace std; //声明一个类。 //类通常在头文件(.h或.hpp)中声明。 class Currency { //默认情况下,成员变量和函数是私有的。 string name; double priceInUSD; //此后的所有成员都是公共的 //直到找到“private:”或“protect...
- 下一篇
Harbor仓库镜像扫描原理
harbor仓库中的镜像扫描这个功能,看似很高大上,其实等你了解了它的底层原理与流程,你就会发现就是做了那么一件事而已,用通俗的一句话概括,就是找到每个镜像文件系统中已经安装的软件包与版本,然后跟官方系统公布的信息比对,官方已经给出了在哪个系统版本上哪个软件版本有哪些漏洞,比如Debian 7系统上,nginx 1.12.1有哪些CVE漏洞,通过对逐个安装的软件包比对,就能知道当前这个镜像一共有多少CVE。当然,如果你是解压版的,那就没啥说的,这个跟windows类似,系统无法在控制面板识别。下面就harbor的具体流程进行简单介绍,让你对这个功能了如指掌。 在了解镜像扫描之前,这里先简单说下镜像的概念,镜像就是由许多Layer层组成的文件系统,重要的是每个镜像有一个manifest,这个东西跟springboot中的一个概念,就是文件清单的意思。一个镜像是由许多Layer组成,总需要这个manifest文件来记录下到底由哪几个层联合组成的。要扫描分析一个镜像,首先你就必须获取到这个镜像的manifest文件,通过manifest文件获取到镜像所有的Layer的地址digest,dig...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- MySQL8.0.19开启GTID主从同步CentOS8
- Red5直播服务器,属于Java语言的直播服务器
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Hadoop3单机部署,实现最简伪集群
- CentOS8编译安装MySQL8.0.19