你开发的系统到底可以支撑多少并发访问?( 二 )


先看一个网络请求是如何到了我们的web容器的 , 一个网络请求从客户端经过若干网线传输和交换机路由器的中间转发 , 到了我们的网卡的时候 , 就是一堆的高低电频信号 , 网卡在接收到这些信号后 , 会有个mac+PHY芯片进行处理 , 首先将物理信号转变为数字信号 , 即01010101这样一串数字 , 然后进行转码 , 转变为帧 , 这就是程序处理网络请求的第一个概念 , 从一个个帧再逐渐转变成包 , 从IP包再转变成TCP包 , 最后转变成http包 , 这就是大学学网络里面讲过的四层协议或七层协议 。这个过程 , 有网卡硬件的处理 , 有CPU和内存的交互 , 还有网卡驱动和操作系统的程序执行 。如下图:

你开发的系统到底可以支撑多少并发访问?

文章插图
 
根据上图简单分析下网络请求处理过程:
  1. 网卡接收高低电频信号经过MAC处理后 , 将数据包先暂存于片内FIFO接收队列 。
  2. 网卡控制器将FIFO队列放入内存的一个环形缓冲区 。
  3. 网卡控制器将环形缓冲区的数据放入内存 , 上半部处理完成 。
  4. 触发软中断 , 开始下半部处理 。
  5. CPU软中断 , 调用网卡驱动程序继续处理 。
  6. 网卡驱动程序通过NAPI开始处理内存中的网络包 。
  7. 操作系统内核网络处理模块开始介入 , 执行大名鼎鼎的netif_receive_skb函数 , 执行完成后 , 网络处理第一大部分完成 , 开始进入协议处理 。
  8. linux内核的socket模块开始介入 , 进行tcp或udp协议处理 。
【你开发的系统到底可以支撑多少并发访问?】根据上图分析 , 我们普通的服务器在处理网络请求时 , 一般有三个瓶颈点 , 带宽、网卡速率和协议处理 。带宽基本上是客户花钱买的 , 一般几十上百兆 , 1G也正常 。网卡速率取决于硬件设备了 , 现在的千兆网卡和万兆网卡比较主流;协议处理算是一个比较重要的瓶颈 , 目前面试宝典中的epoll技术就是协议处理所使用的最重要的一种技术 , 协议处理技术的变革直接导致了网络并发请求和在线连接数从原来的几百到了现在的几十上百万 。
在这些软硬件相互交互的过程中 , 大量前辈针对中断、数据包处理 , 协议处理等做过大量优化 , 有软硬中断、上半部下半部分离处理、NAPI、DMA、Epoll等等 , 这些技术很好的解决了网络请求处理过程中的各种瓶颈 , 发展到目前 , 出现了100Gb的网卡 , 阿里巴巴六年前就开始研究单机千万连接 , 即解决C10M的问题 , 目前在网络处理层面 , 基本上一台物理机可以满足我们正常的十万连接并发处理了 。关于网络编程内容也不是一句两句能说透的 , 此处暂且分析到只要使用了正常的一个服务器 , 并且使用epoll技术 , 适当的估算下并发量和带宽 , 网络处理这块儿不太容易成为瓶颈 。下面我们重点说说epoll和应用层的网络请求处理 。
首先我们可以做个基准测试 , 先随意找一台虚拟机服务器 , 然后部署个Nginx , 直接用wrk来试试基准测试的结果 , 可以看到nginx在一台很普通的服务器上可以支撑8万并发 。如果在这台服务器多跑几个nginx , 基本上可以把网卡打满 , 并发也可以上到十几二十万 , 这就跟本身服务器性能有关了 , 如果是个物理机 , 性能会更高 。nginx只是测试了一个http请求的处理并发 , nginx基准测试完成后 , 可以进一步进行tomcat的基准测试和springboot的基准测试 , 最后使用公司内部的框架做一个网络处理的基准测试 , 得到一个相对合理的极限值 。我们做的结果是nginx单机双实例占用4核可以到15万 , tomcat可以到10万 , springboot和内部封装后的框架可以到9万 。由此看来web容器和spring框架多多少少会损耗一些性能 。此时的瓶颈为CPU , 因为一直在处理网络请求的收发 , 与预期相符 , 在网络处理层面 , CPU、网卡和带宽绝对是瓶颈 。下图是nginx的压测结果 。
你开发的系统到底可以支撑多少并发访问?


推荐阅读