C10K的问题

什么是C10K问题

随着互联网的普及,web的访问呈几何倍数的增长,我们知道一个请求和响应的过程的背后是连接的互换数据,最初的服务器都是基于进程/线程模型的,新到来一个TCP连接,就需要分配1个进程(或者线程)。

而进程和线程又是系统昂贵的资源,一台机器创建的线程数量和进程数量是有限的,不可能无限制的创建。

C10K的核心问题就是即使在硬件资源都满足的情况先,系统也难以承载有10000个客户端连接请求

造成C10K问题的原因

造成C10K问题的本质其实是操作系统的问题,对于传统的阻塞I/O处理方式,当线程或进程创建的足够多时,即使服务器硬件条件满足,也会导致系统的卡顿和崩溃。所以要解决C10K的问题,就应该尽可能的降低CPU的开销和进程的创建。

怎么解决C10K的问题

上面分析了C10K的本质,所以解决办法就围绕着,降低进程的开销,比如让一个进程能够管理多个连接。而如何是一个进程管理多个连接呢?因为在服务端无法知道到底是哪个端口会发来数据。我个人理解具体方法有下面几种:

  1. 同步轮询(select

    方法很简单,直接挨个检查处理各个连接,当所有连接都有数据的时候,方法没有问题,如果有一个连接没有数据,那整个流程就阻塞在哪里,端口就无法进行获得。如果一个进程出来的过多,也会带来性能问题。

  2. 智能跳过轮询 (poll

    这个方法在上面的方法又改进了一步,在读取前先判断当前句柄是否已经是ready状态,如果不是则跳过。

  1. 轮询标记有数据,然后再轮询(epoll

    既然逐个排查所有文件句柄状态效率不高,可以先标记哪些句柄有变化,然后再读取变化的数据。