《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 my.oschina.net/ikende/blog/2250622 「泥水佬」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

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

一、单路存在的问题

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

二、多路复用的优点

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

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

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

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

四、测试消息结构

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

4.1、请求消息

4.2、响应消息

4.3、服务端处理代码

4.4、服务响应对象内容

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

4.5、客户端请求代码

4.6、客户端测试发起代码

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

五、测试配置

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

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

Dotnet core版本是:2.14

六、测试结果

6.1、客户端统计结果

6.2、服务端统计信息

6.3、带宽统计

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

6.4、测试代码

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

文章目录
  1. 1. 一、单路存在的问题
  2. 2. 二、多路复用的优点
  3. 3. 三、通过多路复用实现百万级RPS
  4. 4. 四、测试消息结构
    1. 4.1. 4.1、请求消息
    2. 4.2. 4.2、响应消息
    3. 4.3. 4.3、服务端处理代码
    4. 4.4. 4.4、服务响应对象内容
    5. 4.5. 4.5、客户端请求代码
    6. 4.6. 4.6、客户端测试发起代码
  5. 5. 五、测试配置
  6. 6. 六、测试结果
    1. 6.1. 6.1、客户端统计结果
    2. 6.2. 6.2、服务端统计信息
    3. 6.3. 6.3、带宽统计
    4. 6.4. 6.4、测试代码