多路复用其实并不是什么新技术,它的作用是在一个通讯连接的基础上可以同时进行多个请求响应处理。对于网络通讯来其实不存在这一说法,因为网络层面只负责数据传输;由于上层应用协议的制订问题,导致了很多传统服务并不能支持多路复用;如:http1.1,sqlserver和redis等等,虽然有些服务提供批量处理,但这些处理都基于一个RPS下。下面通过图解来了解释单路和多路复用的区别。

单路存在的问题

每个请求响应独占一个连接,并独占连接网络读写;这样导致连接在有大量时间被闲置无法更好地利用网络资源。由于是独占读写IO,这样导致RPS处理量由必须由IO承担,IO操作起来比较损耗性能,这样在高RPS处理就出现性能问题。由于不能有效的合并IO也会导致在通讯中的带宽存在浪费情况,特别对于比较小的请求数据包。通讯上的延时当要持大量的RPS那就必须要有更多连接支撑,连接数增加也对资源的开销有所增加。

多路复用的优点

多路复用可以在一个连接上同时处理多个请求响应,这样可以大大的减少连接的数量,并提高了网络的处理能力。由于是共享连接不同请求响应数据包可以合并到一个IO上处理,这样可以大大降低IO的处理量,让性能表现得更出色。

通过多路复用实现百万级RPS

多路复用是不是真的如此出色呢,以下在.net core上使用多路复用实现单服务百万RPS吞吐,并能达到比较低的延时性。以下是测试流程: 

由于基础通讯不具备消息包合并功能,所以在BeetleX的基础上做集成测试,主要BeetleX会自动合并消息到一个Buffer上,从而降低IO的读写。

测试消息结构

本测试使用了Protobuf作为基础交互消息,毕竟Protobuf已经是一个二进制序列化标准了。

请求消息

        [ProtoMember(1)]public int ID {  get; set; }[ProtoMember(2)]public Double RequestTime { get; set; }

响应消息

        [ProtoMember(1)]public int EmployeeID { get; set; }[ProtoMember(2)]public string LastName { get; set; }[ProtoMember(3)]public string FirstName { get; set; }[ProtoMember(4)]public string Address { get; set; }[ProtoMember(5)]public string City { get; set; }[ProtoMember(6)]public string Region { get; set; }[ProtoMember(7)]public string Country { get; set; }[ProtoMember(8)]public Double RequestTime { get; set; }

** 服务端处理代码**

        public static void Response(Tuple<IServer, ISession, SearchEmployee> value){Employee emp = Employee.GetEmployee();emp.RequestTime = value.Item3.RequestTime;value.Item1.Send(emp, value.Item2);System.Threading.Interlocked.Increment(ref Count);}public override void SessionPacketDecodeCompleted(IServer server, PacketDecodeCompletedEventArgs e){SearchEmployee emp = (SearchEmployee)e.Message;multiThreadDispatcher.Enqueue(new Tuple<IServer, ISession, SearchEmployee>(server, e.Session, emp));}

服务响应对象内容

            Employee result = new Employee();result.EmployeeID = 1;result.LastName = "Davolio";result.FirstName = "Nancy";result.Address = "ja";result.City = "Seattle";result.Region = "WA";result.Country = "USA";

接收消息后放入队列,然后由队列处理响应,设置请求相应请求时间并记录总处理消息计数。

客户端请求代码

        private static void Response(Tuple<AsyncTcpClient, Employee> data){System.Threading.Interlocked.Increment(ref mCount);if (mCount > 100){if (data.Item2.RequestTime > 0){double tick = mWatch.Elapsed.TotalMilliseconds - data.Item2.RequestTime;AddToLevel(tick);}}var s = new SearchEmployee();s.RequestTime = mWatch.Elapsed.TotalMilliseconds;data.Item1.Send(s);}

客户端测试发起代码

            for (int i = 0; i < mConnections; i++){var client = SocketFactory.CreateClient<BeetleX.Clients.AsyncTcpClient, TestMessages.ProtobufClientPacket>(mIPAddress, 9090);client.ReceivePacket = (o, e) =>{Employee emp = (Employee)e;multiThreadDispatcher.Enqueue(new Tuple<AsyncTcpClient, Employee>((AsyncTcpClient)o, emp));};client.ClientError = (o, e) =>{Console.WriteLine(e.Message);};mClients.Add(client);}for (int i = 0; i < 200; i++){foreach (var item in mClients){SearchEmployee search = new SearchEmployee();Task.Run(() => { item.Send(search); });}}

整个测试开启了10个连接,在这10个连接的基础上进行请求响应复用。

测试配置

测试环境是两台服务器,配置是阿里云上的12核服务器(对应的物理机应该是6核12线程)

服务和客户端的系统都是:Ubuntu 16.04

Dotnet core版本是:2.14

测试结果

客户端统计结果

服务端统计信息

带宽统计

测试使用了10个连接进行多路复用,每秒接收响应量在100W,大部分响应延时在1-3毫秒之间

转载:多路复用实现单服百万级别RPS吞吐

多路复用实现单服百万级别RPS吞吐相关推荐

  1. .net core通过多路复用实现单服务百万级别RPS吞吐

    多路复用其实并不是什么新技术,它的作用是在一个通讯连接的基础上可以同时进行多个请求响应处理.对于网络通讯来其实不存在这一说法,因为网络层面只负责数据传输:由于上层应用协议的制订问题,导致了很多传统服务 ...

  2. 车联网平台百万级消息吞吐架构设计

    前言 在之前的文章中,我们提到车联网 TSP 平台拥有很多不同业务的主题,并介绍了如何根据不同业务场景进行 MQTT 主题设计.车辆会持续不断产生海量的消息,每一条通过车联网上报的数据都是非常珍贵的, ...

  3. 基于单TCP连接的高吞吐模型设计

    对于服务与服务之间往往需要高效的吞吐的信息交互,但在绝大部分服务应用中为了实现高吞吐交互都是基于连接池模式,即通过多个TCP连接来提高吞吐量,这种设计完全是通过增加IO的读写量来实现高效吞吐. 如果能 ...

  4. 如何把百万级别的订单根据金额排序

    前面介绍了一些经典排序算法,它们的时间复杂度最好是 O(nlogn),那 如何把百万级别的订单根据金额排序 是不是觉得可以按照之前学的归并排序.快速排序实现?功能是可以完成,但是效率太低了.今天「码哥 ...

  5. JAVA使用POI如何导出百万级别数据

    用过POI的人都知道,在POI以前的版本中并不支持大数据量的处理,如果数据量过多还会常报OOM错误,这时候调整JVM的配置参数也不是一个好对策(注:jdk在32位系统中支持的内存不能超过2个G,而在6 ...

  6. easyexcel导出百万级数据_百万级别数据Excel导出优化

    这篇文章不是标题党,下文会通过一个仿真例子分析如何优化百万级别数据Excel导出. 笔者负责维护的一个数据查询和数据导出服务是一个相对远古的单点应用,在上一次云迁移之后扩展为双节点部署,但是发现了服务 ...

  7. epoll哪些触发模式_epoll的内部实现 百万级别句柄监听 lt和et模式非常好的解释...

    epoll是Linux高效网络的基础,比如event poll(例如nodejs),是使用libev,而libev的底层就是epoll(只不过不同的平台可能用epoll,可能用kqueue). epo ...

  8. 基于百万级别的站内信设计

    基本上现在的网站都会有站内信功能,主要分为少量(10-999用户),中量(1000-99999用户),大量(100W用户)不同的站内信架构,消耗存储空间,和效率也是不同的.这次要设计的是基于百万级别的 ...

  9. mysql 去重主表数据,两张表结构相同数据(百万级别)

    这里写自定义目录标题 mysql 去重主表数据,两张表结构相同数据(百万级别) 得到两张表的并集,查出主表在并集中出现的主键id 删除主表中重复的id,根据上面sql查出的数据 2.一部删除到位 my ...

最新文章

  1. sql中当前日期加2个月_一文搞定Mysql日期时间函数
  2. Spring Boot Actuator:自定义端点,其顶部具有MVC层
  3. 复练-软考高级-论文写作专题
  4. SQLite学习总结(2)——使用Java操作SQLite
  5. java中的类、成员变量、方法的修饰符。
  6. red hat linux 改ip,Red Hat Enterprise Linux 7(RHEL7)配置静态IP地址
  7. Daemon Process
  8. python操作word.7.19笔记
  9. Macmini 2012Late硬盘异响和Mac下设置apm
  10. 佛罗里达大学计算机博士,2020年佛罗里达大学博士含金量
  11. pytorch 模型微调
  12. Ubuntu19下隐藏桌面图标
  13. 一周小结(七)——从零开始配置VINS-Mono运行环境
  14. java画矩形代码_Java以一种方式绘制矩形
  15. 基于JAVA社区老人健康服务跟踪系统计算机毕业设计源码+数据库+lw文档+系统+部署
  16. ipython和pycharm的区别_ipython和pycharm有什么区别
  17. 无线安全专题_破解篇03--打造个人字典
  18. php redis访问量,redis实现点击量浏览量
  19. 洛谷每日三题之第一天
  20. USB Type A/B/C基本知识和各版本区别

热门文章

  1. 郎永淳妻子抗癌4年路:儿子弃读名校陪治病(转)
  2. STL - MainTao - 博客园
  3. 霍金撰文探讨如何建造时间机器
  4. 在GNS3中使用SecureCRT6.1出错的解决方案
  5. 不要让SOA控制我们的思想
  6. 标准正态分布的积分怎么求?
  7. java ftp取远程服务器时间_在 Java 中如何获取 FTP 服务器上的文件修改时间
  8. FAILED Execution Error, return code 2 from org
  9. 运营商大数据有哪些好处
  10. 大数据分析处理有哪些流程