高性能是每个程序员的追求,无论我们是做一个系统还是写一行代码,都希望能够达到高性能的效果,而高性能又是最复杂的一环,磁盘、操作系统、CPU、内存、缓存、网络、编 程语言、架构等,每个都有可能影响系统达到高性能,一行不恰当的debug日志,就可能将服务器的性能从TPS 30000降低到8000;一个tcp_nodelay参数,就可能将响应时间 从2毫秒延长到40毫秒。因此,要做到高性能计算是一件很复杂很有挑战的事情,软件系统开发过程中的不同阶段都关系着高性能最终是否能够实现。

单服务器高性能的关键之一就是服务器采取的并发模型,并发模型有如下两个关键设计点:

以上两个设计点最终都和操作系统的I/O模型及进程模型相关。

PPC (Process Per Connection)

每次有新的连接就新建一个进程去专门处理这个连接的请求,这是传统的UNIX网络服务器所采用的模型。

https://z3.ax1x.com/2021/09/09/hONYUH.jpg

  1. 父进程接受连接(图中accept)。
  2. 父进程“fork”子进程(图中fork)。
  3. 子进程处理连接的读写请求(图中子进程read、业务处理、write)。
  4. 子进程关闭连接(图中子进程中的close)。

注意,图中有一个小细节,父进程“fork”子进程后,直接调用了close,看起来好像是关闭了连接,其实只是将连接的文件描述符引用计数减一,真正的关闭连接是等子进程也调 用close后,连接对应的文件描述符引用计数变为0后,操作系统才会真正关闭连接,更多细节请参考《UNIX网络编程:卷一》。

TPC (Thread Per Connection)

每次有新的连接就新建一个线程去专门处理这个连接的请求。与进程相比,线程更轻量级,创建线程的消耗比进程要少得多;同时多线程是共享进程内存空间的,线程通信相比进程通信更简单。因此,TPC实际上是解决或者弱化了PPC fork代价高的问题和父子进程通信复杂的问题。

https://z3.ax1x.com/2021/09/20/4GgTv8.png

  1. 父进程接受连接(图中accept)。
  2. 父进程创建子线程(图中pthread)。