简介 高并发的系统架构中,任何细微调整,稍有不注意便会引起连锁反应,只有系统地了解整个网络栈,在处理疑难杂症或者系统优化工作中,才能做到手中有粮心中不慌。在本节,我们概览一个 Linux 系统收包的流程,以便了解高并发系统所面临的性能瓶颈问题以及相关的优化策略。
收包过程 网卡 eth0 收到数据包。 网卡通过 DMA 将数据包拷贝到内存的环形缓冲区(Ring Buffer,在网卡中有 RX Ring 和 TX Ring 两种缓冲)。 数据从网卡拷贝到内存后, 网卡产生 IRQ(Interupt ReQuest,硬件中断)告知内核有新的数据包达到。 内核收到中断后, 调用相应中断处理函数,开始唤醒 ksoftirqd 内核线程处理软中断。 内核进行软中断处理,调用 NAPI poll 接口来获取内存环形缓冲区(ring buffer)的数据包,送至更上层处理。 内核中网络协议栈:L2 处理。 内核中网络协议栈:L3 处理。 内核中网络协议栈:L4 处理。 网络协议栈处理数据后,并将其发送到对应应用的 socket 接收缓冲区。 高并发瓶颈 用户进程调用系统调用陷入内核态的开销。 CPU 响应包的硬中断 CPU 开销 ksoftirqd 内核线程的软中断上下文开销。 RX/TX Ring 优化 处理一个数据包会有各类的中断、softirq 等处理,因为分配给 Ring Buffer 的空间是有限的,当收到的数据包速率大于单个 CPU 处理速度的时,Ring Buffer 可能被占满并导致新数据包被自动丢弃。一个 CPU 去处理 Ring Buffer 数据会很低效,这个时候就产生 RSS、RPS 等多核并发机制来提升内核网络包的处理能力。
但是注意,开启多核并发特性,会挤压业务代码的执行时间,如果业务属于 CPU 密集型,会导致业务性能下降。是否开启多核处理,需要根据业务场景考虑,根据笔者的经验来看,例如此类负载均衡服务器、网关、集群核心转发节点等网络I/O 密集型场景可以尝试优化 RSS、RPS 等配置。