nginx:它的多线程但使用多个进程?

时间:2011-01-21 22:59:43

标签: apache architecture nginx

我试图了解是什么让Nginx如此之快,我有几个问题。

据我所知,Apache会生成一个新进程来为每个请求提供服务,或者生成一个新线程来为每个请求提供服务。由于每个新线程共享虚拟地址空间,因此如果有多个并发请求进入,则内存使用率会不断攀升。

Nginx通过只有一个监听进程(Master),一个执行线程AND 2或3(数字是可配置的)工作进程来解决这个问题。此主进程/线程正在运行事件循环。有效地等待任何传入的请求。当请求进入时,它会将请求提供给其中一个工作进程。

如果我的上述理解不正确,请纠正我

如果以上是正确的,那么我有几个问题:

1。)工作进程是否会产生多个线程并且遇到与apache相同的问题?

2。)或者nginx速度快,因为它的基于事件的架构在它下面使用了非阻塞IO。也许工作进程产生了非阻塞IO的线程,是吗?

3。)“完全”是什么“基于事件的架构”,有人可以真正简化它,对于像我这样的soemone来理解。它是否仅适用于非阻塞io或其他类似的东西?

我得到了c10k的引用,我试图通过它,但我不认为它基于事件的基础。对于非阻塞IO来说似乎更多。

3 个答案:

答案 0 :(得分:51)

Apache使用多个线程为每个请求提供自己的执行线程。这对于避免在使用同步I / O时阻塞是必要的。

Nginx仅使用异步I / O,这会阻止非问题。 nginx使用多个进程的唯一原因是充分利用多核,多CPU和超线程系统。即使支持SMP,内核也无法在多个CPU上调度单个执行线程。每个逻辑CPU至少需要一个进程或线程。

所以区别在于,nginx只需要 足够的工作进程才能充分利用SMP,而Apache的架构需要创建一个新的线程(每个都有自己的堆栈)大约~8MB)每个请求。显然,在高并发性的情况下,Apache将使用更多的内存,并且在维护大量线程时会承受更大的开销。

答案 1 :(得分:17)

从概念的角度来看,这并不是很复杂。我会尽力清楚,但我必须做一些简化。

基于事件的服务器(如nginxlighttpd)使用事件监视系统的包装器。例如。 lighttpd使用libevent来抽象更高级的高速事件监控系统(另请参阅libev)。

服务器使用每个连接的简单状态机跟踪它具有的所有非阻塞连接(写入和读取)。当有新数据可用或何时可以写入更多数据时,事件监视系统会通知服务器进程。就像你知道套接字编程一样,它就像select()类固醇。然后,服务器进程只使用一些高级函数(如sendfile())发送请求的文件,或者使用套接字将请求转换为CGI进程进行通信(此套接字将使用事件监视系统进行监视,就像其他网络连接一样。)

This链接了很多关于nginx内部的重要信息,以防万一。我希望它有所帮助。

答案 2 :(得分:6)

Apache不会为每个请求生成新线程。它维护一个线程缓存或一组预分叉进程,并将请求分配给它。并发请求的数量受到子/线程数的限制,但是apache并没有为每个请求产生一个新的线程/子进程,这会非常慢(即使有线程,每次请求的创建和拆除都会太慢) )

Nginx使用主工作者模型。主进程处理加载配置和创建/销毁/维护工作程序。就像apache一样,它开始时已经运行了许多预先分叉的进程,每个进程都是一个worker(其中一个是“master”进程)。每个工作进程共享一组侦听套接字。每个工作进程都接受连接并处理它们,但是每个工作程序可以同时处理数千个连接,这与apache不同,apache每个worker只能处理1个连接。

nginx实现这一目标的方式是通过“多路复用”。它不使用libevent,它使用专门为nginx设计的自定义事件循环,并随着nginx软件的开发而在开发中增长。多路复用通过使用循环来通过在一个数据/新连接/每个循环迭代的每个连接/对象上操作的块来“递增”通过程序块来工作。它都基于后端,如Epoll()kqueue()和select()。你应该阅读哪些