单线程NGINX如何处理这么多连接?

use*_*744 5 sockets asynchronous epoll nginx

NGNIX使用epoll通知来了解套接字上是否有任何要读取的数据。

假设:有两个对服务器的请求。nginx收到关于这两个请求的通知,并开始执行以下操作:

  • 收到第一个请求

  • 解析头

  • 检查胸围(体型)

  • 发送第一个请求到上游服务器

  • 等等

nginx是单线程的,并且只能同时执行一项操作。

但是第二个请求会怎样?

  1. 在解析第一个请求时,nginx是否收到第二个请求?

  2. 还是在完成第一个请求后开始处理第二个请求?

  3. 或其他我不理解的东西。

如果1.是正确的,那么我不知道在单个线程中怎么可能。

如果2.正确,那么nginx怎么会这么快?因为nginx会顺序处理所有传入请求。在任何给定时间只能处理一个请求。

请帮助我理解。谢谢

Zab*_*ula 5

Nginx不是单线程应用程序。它不会为每个连接启动一个线程,但会在启动期间启动多个工作线程。在http://www.aosabook.org/en/nginx.html中对nginx架构进行了很好的描述。

实际上,单线程无阻塞应用程序是单处理器硬件最有效的设计。当我们只有一个CPU并且应用程序完全不阻塞时,应用程序可以充分利用CPU的功能。非阻塞应用程序意味着应用程序不会调用任何可能等待事件的函数。所有IO操作都是异步的。这意味着应用程序不会read()从套接字简单调用,因为调用可能要等到数据可用时才能进行。非阻塞应用程序使用某种机制来通知应用程序数据可用并且可以调用read()不会有电话等待的风险。因此,理想的非阻塞应用程序对于系统中的一个CPU只需一个线程。由于nginx使用非阻塞调用,因此多个线程中的处理没有任何意义,因为没有CPU可以执行其他线程。

当网卡发出中断时,从网卡到缓冲区的实际数据接收将在内核中完成。然后,nginx在缓冲区中获取一个请求并进行处理。在当前请求处理完成之前或直到当前请求处理需要可能阻止的操作(例如磁盘读取)之前,开始处理另一个请求没有任何意义。