作者 | 泥水佬 来源 | my.oschina.net/ikende/blog/2250622

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

测试结果

客户端统计结果

服务端统计信息

带宽统计

测试代码

https://github.com/IKende/BeetleX/blob/master/samples/MultiplexingConnectionTest.zip

猜你喜欢

1、GitHub 标星 3.2w!史上最全技术人员面试手册!FackBoo发起和总结

2、如何才能成为优秀的架构师?

3、从零开始搭建创业公司后台技术栈

4、程序员一般可以从什么平台接私活?

5、37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...

6、滴滴业务中台构建实践,首次曝光

7、不认命,从10年流水线工人,到谷歌上班的程序媛,一位湖南妹子的励志故事

8、15张图看懂瞎忙和高效的区别!

用IO多路复用,实现每秒百万并发的原理你懂吗?相关推荐

  1. nginx 多进程 + io多路复用 实现高并发

    一.nginx 高并发原理 简单介绍:nginx 采用的是多进程(单线程) + io多路复用(epoll)模型 实现高并发 二.nginx 多进程 启动nginx 解析初始化配置文件后会 创建(for ...

  2. 网络编程实战之高级篇, 彻底解决面试C10k问题, 高并发服务器, IO多路复用, 同时监视多个IO事件

    目录 一.前言 二.IO多路复用的理解 三.IO多路复用的发展 select poll epoll ​四.C10K服务端代码 五. 总结 一.前言 网络入门篇,从操作系统的层次推开网络大门 网络入门基 ...

  3. io多路复用·零拷贝·while死循环cpu

    文章目录 引用文章 问题 io多路复用效率为什么这么高 epoll和select/poll什么时候用 epoll的LT和ET 从 jdk 的 nio 到 epoll 源码与实现内幕全面解析 io多路复 ...

  4. Python之路,Day9 - 线程、进程、协程和IO多路复用

    参考博客: 线程.进程.协程: http://www.cnblogs.com/wupeiqi/articles/5040827.html http://www.cnblogs.com/alex3714 ...

  5. 【面试必问】支撑百万并发的IO多路复用技术你了解吗?

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

  6. java基础巩固-宇宙第一AiYWM:为了维持生计,四大基础之OS_Part_2整起~IO们那些事【包括五种IO模型:(BIO、NIO、IO多路复用、信号驱动、AIO);零拷贝、事件处理及并发等模型】

    PART0.前情提要: 通常用户进程的一个完整的IO分为两个阶段(IO有内存IO.网络IO和磁盘IO三种,通常我们说的IO指的是后两者!):[操作系统和驱动程序运行在内核空间,应用程序运行在用户空间, ...

  7. Unix C语言编写基于IO多路复用的小型并发服务器

    背景介绍 如果服务器要同时处理网络上的套接字连接请求和本地的标准输入命令请求,那么如果我们使用accept来接受连接请求,则无法处理标准输入请求;类似地,如果在read中等待一个输入请求,则无法处理网 ...

  8. PostgreSQL中的io多路复用--select和epoll实现

    某天和同事闲聊,同事发现一个现象,PostgreSQL在空闲状态时(没有active连接),主进程的pstack显示一直在调用/lib64/libc.so.6的__select_nocancel () ...

  9. 漫谈五种IO模型(主讲IO多路复用)

    首先引用levin的回答让我们理清楚五种IO模型 1.阻塞I/O模型 老李去火车站买票,排队三天买到一张退票. 耗费:在车站吃喝拉撒睡 3天,其他事一件没干. 2.非阻塞I/O模型 老李去火车站买票, ...

  10. Python网络编程:IO多路复用

    io多路复用:可以监听多个文件描述符(socket对象)(文件句柄),一旦文件句柄出现变化,即可感知. 1 sk1 = socket.socket() 2 sk1.bind(('127.0.0.1', ...

最新文章

  1. 蓝色梦想,再次起航 | 水下目标检测算法比赛正式开赛!
  2. 亲和数 杭电2040
  3. 数据资产管理:大数据时代的新风口
  4. 艾永亮:不做读书人生意的书店,如此不正经却年赚超12亿?
  5. 如何彻底解决Variable used in lambda expression should be final or effectively final
  6. Java实训—VII,VIII
  7. 世界自然基金会推出区块链工具以跟踪食品供应链
  8. C语言作用域与生存期
  9. R语言广义加性模型GAMs分析温度、臭氧环境数据绘制偏回归图与偏残差图
  10. 微信小程序_调用openAi搭建虚拟伙伴聊天
  11. python 发送邮件附件很慢_python发送邮件附件
  12. javascript 闭包_了解JavaScript闭包:实用方法
  13. java试题库管理系统源代码_Java试题库管理源代码
  14. React部署到 Tomcat上 使用 BrowserRouter不能刷新404的问题
  15. IE浏览器安装Activex插件
  16. Python OpenCV绘画实现 油画效果、水彩效果
  17. 电大2019计算机试题及答案实操题,2019电大计算机WORD统考题库及答案.doc
  18. 光伏全年数据,风电数据,光伏出力。 因素 辐射 温度 气压 湿度 可用于人工神经网络数据分析;
  19. usb high speed chirp
  20. 低速自动驾驶:新创公司弯道超车 Waymo 的最佳方法?

热门文章

  1. iOS WebView生成长截图的第三种解决方案
  2. VR AR体验或成2017圣丹斯电影节“新主角”
  3. 1. 初识ZooKeeper。
  4. Linux IPC udp/ip socket 编程
  5. Android模拟器SDL_app:emulator.exe 解决方法
  6. 「leetcode」406.根据身高重建队列【贪心算法】详细图解
  7. leetcode[0142]环形链表II,判断是否存在环形链表并找到环形的入口
  8. Acrobat Pro DC 教程,如何编辑 PDF 文件中的文本和图片?
  9. indesign教程,如何设置边距和分栏?
  10. 如何在 Mac 上使用“接力”回到上次离开的地方?