nginx的IO复用和epoll模型

IO复用

首先用python演示普通worker的socket操作,是如何应对请求的?

nginx的IO复用和epoll模型

从上述代码可以看出worker进程一共进行了四步:

  • accpet() 与客户端进行连接
  • recv() 接收客户端发过来的数据
  • send() 向客户端发送数据
  • close() 关闭此次连接

经历这四步时,如果在recv()时,发生了IO堵塞,那么请求就会一直等待,直到close(),才会建立新连接。那么如何在IO阻塞时,也能处理其他客户的连接?

nginx的IO复用和epoll模型

以上代码演示了IO复用(多线程处理),这种方式解决了多个用户并发请求一个WEB网站,让每一个 socket复用完每个IO流的请求。nginx正是采取了这种方式,只是它的源码更复杂。

IO复用和epoll模型

在介绍nginx的epoll模型时,我们要先看一下传统IO多路复用模型的select和poll。

举个例子:有大量用户(100万个)同时与一个进程保持TCP连接,而在某一时刻只有少量(几十上百)是活跃的(即能接收数据包),那么在这一时刻只需处理这些少量请求即可!

传统select和poll:每次收集事件,都把这100万连接的套接字传给操作系统(用户态内存到内核内存的大量复制),而由操作系统内核寻找这些链接上没有处理的事件(浪费内存)。

epoll:将select和poll结合起,使用三步来操作。

  1. 调用epoll_creat建立一个epoll对象。
  2. 调用epoll_ctl向epoll对象中添加这100万个连接的套接字。
  3. 调用epoll_wait收集发生事件的连接。这是主要的步骤,将事件的连接放入一个链表,只要在链表中寻找发生连接的事件,不用去遍历这100万个连接。

总结

nginx正是采用了多路IO复用+epoll方式来应对高并发。以master控制多个worker,实现对多核CPU的利用。


分享到:


相關文章: