使用Apache2(或Nginx)处理Http请求。是为每个或一组N个请求创建新进程吗?

时间:2016-09-10 10:04:32

标签: apache http tomcat nginx httpserver

Web服务器(WS)(如apache2或nginix(或像tomcat(TC)这样的容器)是否会创建一个处理传入请求的新进程。我关心的是支持大量并行用户的服务器(比如20K +并行用户) )。
我认为负载均衡发生在Web服务器的另一端(如果它用于前面的Tomcat等)。因此理论上,单个Web服务器应该接受所有(20K +)传入请求,然后才能将负载分配给支持它的其他服务器。 所以,问题是:Web服务器(WS)是否在一个进程中处理所有这些请求,或者它巧妙地产生其他进程以帮助共享工作(我知道"客户端 - 服务器"绑定发生虽然 - client_host:random_port 加上 server_host:fixed_port )。

参考:在阅读本文之前:Fronting Tomcat with Apache我认为这是一个完成所有智能工作的单一流程。但在本文中提到了MPM(多处理模块)

  

它结合了两个世界的最佳组合,拥有一组子进程,每个子进程都有一组独立的线程。有些网站使用这种技术运行10K +并发连接。

随着它的发展,它变得越来越复杂,因为线程也像上面提到的那样产生。 (这些不是通过调用服务方法为每个单独的请求提供服务的tomcat线程,但这些是Apache WS上的线程来处理请求并将它们分发给节点进行处理)。 如果有人使用MPM。对这一切如何运作的进一步解释将是很好的 像 - 的问题 (1)随着子过程的产生,它的确切角色是什么。子进程是仅用于将请求调解到tomcat还是其他任何内容。如果是这样,那么在子进程从TC获得响应后,子进程是否会将响应转发给父进程或直接转发给客户端(因为它可以知道 client_host:random_port 来自父进程。我不确定理论上是否允许这样做,尽管子进程无法接受任何新请求,因为 fixed_port 只能绑定到一个进程已经与父流程联系在一起 (2)子进程或父进程共享哪种负载。它必须与(1)中的几乎相同。但我不确定的是,即使在理论上,如果一个线程可以直接将请求发送给客户端。

1 个答案:

答案 0 :(得分:1)

Apache历史上使用prefork处理模型。在该模型中,每个请求==单独的操作系统(OS)过程。它称之为“prefork”,因为Apache在其中分配了一些备用进程和进程请求。如果preforked进程的数量不够 - Apache fork new。优点:流程可以执行其他模块或流程,而不关心他们做什么;缺点:每个请求=一个进程,使用的内存太多,操作系统分叉也可能对您的请求很慢。

其他型号的Apache - worker MPM。几乎与prefork相同,但不是使用OS进程而是使用OS线程。线程 - 它就像轻量级进程。一个OS进程可以使用一个内存空间运行多个线程。 Worker MPM使用更少的内存和快速创建的新线程。缺点:模块需要支持线程,模块崩溃可能会崩溃所有操作系统进程的所有线程(但这对你来说并不重要,因为你只使用apache作为反向代理)。其他缺点:在线程之间切换时CPU switching context

所以是的,在你的情况下,工人比prefork好多了,但是......

但我们有Nginx :) Nginx使用其他模型(顺便说一句,Apache也有事件MPM)。在这种情况下,您只有一个流程(嗯,可以是几个流程,见下文)。这个怎么运作。新请求上升特殊事件,OS进程唤醒,接收请求,准备答案,写答案和睡眠。

你可以说“哇,但这不是多任务”并且是对的。但这个模型和简单的顺序请求处理之间有一个很大的区别。如果您需要编写大数据来减慢客户端,会发生什么?以同步方式,您的流程需要等待确认数据接收并且仅在处理新请求之后。 Nginx和Apache事件模型使用异步模型。 Nginx告诉操作系统发送一些数据将这些数据写入OS缓冲区并进入睡眠状态或处理新请求。当OS发送数据时 - 特殊事件将被发送到nginx。所以,主要区别--Nginx不等待I / O(如连接,读取,写入),Nginx告诉操作系统他想要和OS发送事件到Nginx比这个任务准备就绪(套接字连接,数据写入或新数据准备读取在本地缓冲区)。此外,现代操作系统可以与HDD(读/写)异步工作,甚至可以直接从HDD发送文件到tcp套接字。

当然,此Nginx流程中的所有数学运算都将阻止此流程,并停止处理新的和现有的请求。但是当主要工作流程与网络一起工作时(反向代理,转发对FastCGI或其他后端服务器的请求)以及发送静态文件(异步) - Nginx可以在一个操作系统进程中同时处理数千个请求!此外,因为OS(和一个线程)的一个进程--CPU将在一个上下文中执行它。

我之前告诉过--Nginx可以启动一些操作系统进程,并且每个进程都将由操作系统分配给CPU内核。几乎没有理由分叉更多的Nginx操作系统进程(只有一个原因可以做到:如果你需要做一些阻塞操作,但是简单的反向代理和后端平衡 - 不是这种情况)

所以,专业人士:减少CPU上下文切换,减少内存(与工作者MPM相比),快速连接处理。更多优点:Nginx作为HTTP负载均衡器创建并具有很多选项(在商业Nginx Plus中甚至更多)。缺点:如果你在操作系统进程中需要一些硬数学,这个过程将被阻止(但你在Tomcat中所有数学,所以Nginx只有平衡器)。

PS:错误修复将在稍后时间推出。另外,我的英语不好,所以总是欢迎修复:)

PPS:回答有关TC帖子数量的问题,在评论中提出(评论时间过长):

了解它的最佳方式 - 使用压力加载工具对其进行测试。因为此数字取决于应用程序配置文件响应时间不足以帮助回答。因为,例如,200%100%数学(100%cpu界限)与50ms数学+ 150ms睡眠等待数据库答案之间的差异很大。

如果应用程序是100%CPU绑定 - 可能每个核心一个线程,但在实际情况下,所有应用程序也在I / O中花费一些时间(接收请求,向客户端发送答案)。

如果应用程序使用I / O并且需要等待来自其他服务(例如数据库)的答案,则此应用程序会在休眠状态下花费一些时间,并且CPU可以处理其他任务。

因此,创建接近实际负载的请求数量并运行压力测试的最佳解决方案是增加并发请求的数量(以及确定的TC工作者数量)。找到可接受的响应时间并修复此线程数。当然,需要先检查一下它是不是数据库故障。

当然,这里我只谈论动态内容,必须在tomcat之前处理来自磁盘的静态文件请求(例如,通过Nginx)。