为何Nignx的高并发能力比Apache强那么多

Nginx和Apache都是Web服务器。Nginx能抗住几万的高并发,而Apache却只能几千。主要的原因在于IO多路复用的选择。

白话版:

专业版:

我们先来理解什么是用户态和内存态:

内核态: 

     CPU可以访问内存所有数据, 包括外围设备, 例如硬盘, 网卡. CPU也可以将自己从一个程序切换到另一个程序

用户态

      只能受限的访问内存, 且不允许访问外围设备. 占用CPU的能力被剥夺, CPU资源可以被其他程序获取

为什么要有用户态和内核态:

      由于需要限制不同的程序之间的访问能力, 防止他们获取别的程序的内存数据, 或者获取外围设备的数据, 并发送到网络, CPU划分出两个权限等级 -- 用户态 和 内核态

selec缺点:

  1. 每次调用select都需要把fd从用户态拷贝到内核态,开销比较大
  2. 每次都需要在内核遍历传入的fd
  3. select支持文件数量比较小,默认是1024

epoll:

     select/poll只提供了一个函数,select/poll函数。但epoll一下子就提供了3个函数。

     epoll_create:创建一个epoll句柄

     epoll_ctl:注册要监听的事件类型

    epoll_wati:等待事件产生

epoll优点:

  1. 每次注册新事件到epoll句柄都会把所有的fd拷贝进来,而不是在epoll_wait中重复拷贝,这样保证fd只会被拷贝一次
  2. epoll不是像select/poll那样每次都把fd加入等待队列,epoll为每个fd指定一个回调函数,当设备就绪时,唤醒等待队列的等待者就会调用他的回调函数,这个回调函数会把就绪的fd加入一个就绪链表,epoll_wait就是在这个就绪链表中查看有没有就绪fd
  3. epoll没有fd数目限制

 总结:

(1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用 epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在 epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的 时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。

(2)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要 一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内 部定义的等待队列)。这也能节省不少的开销。 

 

专业版来源:https://yq.aliyun.com/articles/48668 

站在巨人的肩膀上成长,文章思想和经验来自网络上的大神,未能一一列举,在此,谢过不杀之恩。 

猜你喜欢

转载自blog.csdn.net/H_L_S/article/details/83926396