问题描述
课程中的项目:
4 台虚拟机,1 台作为服务器接收 TCP 连接,3 台作为客户端发起连接,在服务器端达到 100 w 的并发连接量
已排查的问题:
- 进程 fd 数量的限制
每个进程的 fd 数量默认限制是1024,修改为了1048576(2 ^ 20)
- 服务器端 socket 五元组耗尽
服务器端:1 个监听端口 --> 20 个监听端口
客户端:更改可用端口,默认可用端口为 32768 - 60999 也就是20000多个 – > 更改为 1024 - 65535 也就是60000多个
修改后一个客户端就可以创建 120 w 个 socket,解决了五元组耗尽的问题
- tcp_mem / tcp_rmem / tcp_wmem 参数修改
- tcp_mem: 三元组,表示TCP内存管理的全局参数。三个元素分别代表最小内存限制(low)、压力模式的内存限制(pressure)、最大内存限制(high)。这些值影响系统在不同内存压力下分配和回收TCP缓冲区的方式。当系统内存不足时,它将根据这些参数来调整TCP缓冲区的大小。单位是页(page,一般是 4 kB)
- tcp_wmem: 三元组,表示TCP发送缓冲区的大小参数。它包含了最小大小(low)、默认大小(default)和最大大小(high)。这些值影响TCP发送缓冲区的大小,从而影响发送数据时的性能和行为。
- tcp_rmem: 三元组,表示TCP接收缓冲区的大小参数。它包含了最小大小(low)、默认大小(default)和最大大小(high)。这些值影响TCP接收缓冲区的大小,从而影响接收数据时的性能和行为。
以上问题排查后在 UTM 虚拟机中,能够达到 100w 的连接量,但是在 连接断开 的时候,也就是在一个客户端 ctrl + c 之后,服务器端会直接卡死,ssh 也会断掉
一般性原因
针对大量连接同时断开时,服务器 CPU 和内存使用飙升是正常情况,一般性原因有以下:
- 资源清理和垃圾回收:当连接关闭时,服务器需要清理和回收分配给这些连接的资源。这个过程可能涉及内存释放、缓存清理和数据结构更新,这些操作可能会暂时增加 CPU 和内存使用。
- 并发处理高峰:在处理大量并发断开连接的情况下,服务器可能需要同时执行多个资源清理操作,这会导致 CPU 使用率上升。
- 网络堆栈压力:大量的连接和断开事件可能会对服务器的网络堆栈造成压力,特别是如果这些连接在很短的时间内快速建立和断开。
- 同步和锁争用:在多线程环境中,线程可能需要等待锁释放才能访问或修改共享资源,这可能导致 CPU 等待时间增加,特别是在高并发情况下。
- 异常检测和处理:服务器可能需要检测并处理断开连接时的任何异常情况,这可能包括日志记录、错误检查等,这些操作可能占用额外的 CPU 和内存资源。
- 内存泄漏:如果服务器代码在处理连接断开时没有正确管理内存(如未能释放不再需要的内存),可能会发生内存泄漏,导致内存使用不断增加。
- 操作系统和网络队列:操作系统层面的网络队列可能在大量连接断开时积压,处理这些队列可能会增加 CPU 负载。
- 数据库和磁盘 I/O:如果服务器在连接断开时需要更新数据库或执行磁盘 I/O 操作,这也可能导致资源使用的增加。
我的情况是在 Windows 平台上不会出现卡死,而 mac 上出现断连卡死,判断是虚拟机的问题,因此排查了虚拟机网络模式和虚拟网卡,同时通过更换虚拟机软件,也发现有不同的情况出现
虚拟机网络模式(不是致命原因,但有一定影响)
一般的虚拟机软件中可以选择虚拟机与主机之间的网络模式,UTM 和 VMware Fusion都有:桥接和共享模式,这是两种常用的网络模式,先上结论:NAT 模式的隔离程度更低,桥接模式下每个虚拟机有独立的 IP,隔离程度更高,因此桥接模式比 NAT 模式能够承载的并发断开连接能力更强
NAT 模式
- 定义:在 NAT 模式下,虚拟机共享宿主机的 IP 地址。宿主机上运行的 NAT 服务为虚拟机提供网络访问,并处理虚拟机与外部网络之间的网络地址转换。
- 工作原理:虚拟机发送的所有网络请求都经过宿主机,由宿主机转发到外部网络。从外部网络返回的数据也同样经过宿主机再转发给虚拟机。
- 虚拟机拥有一个私有(内部)网络地址 192.168.64.2。
- 宿主机在这个私有网络中通常有一个固定的 IP 地址, 192.168.64.1,它充当虚拟机的网关。
- 向外发送
- 当虚拟机发送数据到外部网络时(比如访问互联网),数据包首先发送到宿主机(网关)。
- 宿主机接收到这些数据包后,将它们的源地址(虚拟机的私有地址)转换为宿主机的公共 IP 地址。
- 数据包被发送到互联网上,外部服务器看到的是宿主机的公共 IP 地址作为请求的源地址。
- 接收外部数据包
- 当外部服务器响应请求时,它将数据发送回宿主机的公共 IP 地址。
- 宿主机接收到响应后,根据之前建立的 NAT 表,将数据包的目标地址从宿主机的公共 IP 地址转换回虚拟机的私有 IP 地址。
- 数据包最终被发送到虚拟机。
- 端口转发
- 不开启端口转发:虚拟机可以向外发送数据 ,但虚拟机上运行的服务(如网页服务器、FTP 服务器等)将无法从外部网络直接访问。
- 假设你在虚拟机上运行了一个 web 服务器,监听在 80 端口。
- 从虚拟机内部,你可以通过 http://localhost 或 http://192.168.64.2 访问这个 web 服务器。
- 但是,从外部网络(如另一台电脑或互联网)尝试访问这个 web 服务器将会失败,因为宿主机的 NAT 设置阻止了直接访问虚拟机的内部服务。
- 开启端口转发:指定宿主机的某个端口来转发到虚拟机的特定端口。这样,当从外部网络向宿主机的该端口发送请求时,请求会被转发到虚拟机上的相应服务。
- 你在宿主机上设置了端口转发,将宿主机的 8080 端口转发到虚拟机的 80 端口。
- 从外部网络,你现在可以通过访问
http://宿主机的公共IP地址:8080
来访问虚拟机上的 web 服务器。 - 宿主机接收到端口 8080 上的请求后,会自动将其转发到虚拟机的 80 端口。
- 不开启端口转发:虚拟机可以向外发送数据 ,但虚拟机上运行的服务(如网页服务器、FTP 服务器等)将无法从外部网络直接访问。
- 优点:
- 安全性较高:虚拟机不直接暴露在外部网络上。
- 无需额外的 IP 地址:所有虚拟机共享宿主机的 IP 地址。
- 缺点:
- 网络配置复杂:可能需要在宿主机上设置端口转发规则才能从外部网络访问虚拟机的特定服务。
- 性能开销:由于额外的地址转换步骤,可能会有轻微的性能影响。
桥接模式
- 定义:在桥接模式下,虚拟机直接连接到宿主机所在的物理网络,就像网络上的另一台独立计算机一样。
- 工作原理:虚拟机通过宿主机的网络适配器获取自己的 IP 地址,并直接与外部网络通信,无需经过宿主机的网络地址转换。
- 优点:
- 直接网络访问:虚拟机可以像宿主机一样直接访问网络,易于设置和管理。
- 性能:通常提供比 NAT 更好的网络性能。
- 缺点:
- 安全风险:虚拟机直接暴露在网络上,可能面临更多的安全威胁。
- IP 地址需求:每台虚拟机需要一个独立的 IP 地址。
虚拟网卡
只在 UTM 上找到了网卡的配置选择,没有在 VMware Fusion 中找到网卡选择。针对 UTM 的虚拟网卡选择,有如下的选项
先上结论:vmxnet3 网卡隔离水平高于 virtio-net-pci 网卡的隔离水平,因此使用 vmxnet3 网卡能达到更好的并发断连能力
网卡(Network Interface Card,NIC)
- 网卡,也称为网络接口卡或网络适配器,是一种硬件设备,用于连接计算机到计算机网络。网卡的功能是作为物理层和数据链路层的接口,实现计算机与网络的物理连接,以及在计算机和网络之间传输数据。
- 物理网卡:在物理计算机中,网卡通常是一个插在主板上的扩展卡,或者是集成在主板上的芯片组。
- 虚拟网卡:在虚拟机中,网卡表现为一个虚拟的网络接口,由虚拟化软件模拟,允许虚拟机连接到虚拟网络或实际网络。
网卡驱动
- 网卡驱动是软件组件,允许操作系统和网卡硬件进行交互。驱动程序负责控制和管理硬件设备的操作,包括发送和接收数据、处理网络数据包、以及执行其他与网络相关的功能。网卡驱动通常是操作系统的一部分,或者由硬件制造商提供,需要在操作系统中安装。
- 物理网卡驱动:用于控制物理硬件网卡的操作。
- 虚拟网卡驱动:用于控制虚拟机中模拟的网络接口,例如
VirtIO
或vmxnet3
驱动。
两种虚拟网卡驱动在并发上表现的区别:
- TCP 协议栈实现:
- 不同的网卡驱动可能会以不同的方式与虚拟机内的 TCP/IP 协议栈交互。这可能影响到网络堆栈在极端情况下的表现,例如大量并发连接的建立和断开。
- 资源管理:
- 驱动程序如何管理和分配网络资源(如缓冲区、队列等),在高负载时可能会显著影响性能和稳定性。
-
vmxnet3
可能在这方面进行了更多的优化,以适应高并发连接的需求。
测试结果
virtio-net-pci
- 桥接 / NAT:2k 连接量就会卡死
vmxnet3
- 桥接:
- 5w 不会卡死;
- 10w 不会卡死;
- 20w 不会卡死;
- 60w ssh会很卡,但是等待半分钟左右,并没有卡死,正常运行;
- 100w 同样不会卡死;
- 断开连接的时候可以看到cpu的负载飙升
- NAT:
- 10w 不会卡死;
- 20w 竟然卡死了,broken pipe(好像是个意外事件),但虚拟机没卡死,可以重新ssh连接;
- 60w / 100w 没卡死,但ssh卡出去了,报错信息与virtio网卡的报错信息不同(virtio是broken pipe,且卡死)
- 60w / 100w 断开时: ssh断掉了,虚拟机内部还可以正常运行,过一段时间重新连接ssh还是可以连上的,也就是虚拟机并没有卡死
理解与思考
在 UTM 中:文章来源:https://www.toymoban.com/news/detail-792714.html
- virtIO:相当于水管。虚拟机与宿主机之间通信,virtIO 把虚拟机当成一个大的进程,虚拟机之间的通信相当于宿主机之间的进程通信,底层使用的本地 socket 通信(通知),使用共享内存进行通信。当一个客户端fd关闭的时候,virtIO 会有两次通知, 一次是socket 通知虚拟机有数据来了,另一次是共享内存 读取具体的数据
- vmxnet3:相当于开了一个水池。通过软件模拟的物理网卡的方式
- NAT:在 mac 上构建一个网关,虚拟机是这个网关下的节点。虚拟机与宿主机共享一块网卡
- 桥接:虚拟机与 mac 是平级的
- vmxnet 与 桥接/共享 的关系。 vmxnet3相当于水池,桥接/共享是水池的位置。virtio是水管供水
- 处理并发断连量:vmxnet+桥接 > vmxnet+共享 > virtIO+桥接/共享(只要用virtIO驱动就1k 级别的断连直接死机) ==> 差别在于隔离的级别
在 VMware Fusion 中:文章来源地址https://www.toymoban.com/news/detail-792714.html
- 桥接 / 共享 断连时都不会卡死
- 说明 VMWare Fusion 在隔离程度上比 UTM 更好
到了这里,关于虚拟网卡、网络模式造成的tcp并发量的问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!