【问题标题】:How can a single-threaded NGINX handle so many connections?一个单线程的 NGINX 如何处理这么多的连接?
【发布时间】:2015-04-29 17:04:26
【问题描述】:

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

假设: 服务器有两个请求。 nginx 收到关于这两个请求的通知并开始:

  • 收到第一个请求

  • 解析ist标头

  • 检查边界(体型)

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

nginx是单线程的,一次只能做一个操作。

但是第二个请求会发生什么?

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

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

  3. 或者其他我不明白的东西。

如果 1. 是正确的,那么我不明白它是如何在单个线程中实现的。

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

请帮助我理解。 谢谢

【问题讨论】:

  • 可能是相关的:unix 套接字被证明比使用 TCP 慢。还有一件事:nginx 是单线程的,但创建的工作人员很少,默认情况下是 4 个,你的问题是关于一个特定工作人员内部发生了什么?
  • 在这里查看我的答案以获得解释:stackoverflow.com/a/19324665/362536

标签: sockets asynchronous nginx epoll


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 2013-05-21
    • 2016-08-31
    • 2018-01-27
    • 1970-01-01
    相关资源
    最近更新 更多