【问题标题】:Handling Http Request with Apache2 (or Nginx). Does a new process gets created for each or a set of N requests?使用 Apache2(或 Nginx)处理 Http 请求。是否为每个或一组 N 个请求创建一个新进程?
【发布时间】:2017-01-18 09:27:58
【问题描述】:

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+ 并发连接。

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

【问题讨论】:

    标签: apache http tomcat nginx httpserver


    【解决方案1】:

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

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

    所以是的,在你的情况下,worker 比 prefork 好得多,但是......

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

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

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

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

    因此,优点:更少的 CPU 上下文切换、更少的内存(也与工作 MPM 相比)、快速的连接处理。更多优点:Nginx 创建为 HTTP 负载均衡器,并且有很多选择(在商业 Nginx Plus 中甚至更多)。缺点:如果您需要在 OS 进程中进行一些数学运算,该进程将被阻止(但您在 Tomcat 中的所有数学运算,因此仅 Nginx 平衡器)。

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

    PPS:回答有关 TC 线程数量的问题,以 cmets 形式提出(作为评论发布太长):

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

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

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

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

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

    【讨论】:

    • 详细信息。德克萨斯州。我想问的另一个重要配置参数 - 每个 tomcat 工作程序可以使用的线程数的安全值是多少。 (最好作为处理器核心数量的函数 - NC 和 HT 数量(如果每个处理器 HTP 有的话)。我有 NC=4 和 HTP=2,所以可用的逻辑处理器总数为 8。那么我的这个工作线程的总数应该是多少。用很少的信息回答这可能会很棘手,但一些指导方针会有所帮助。发送
    • 我在上面的回答中以 PPS 的形式回答了您的问题,因为此评论的字符太多。
    • 这就是我的问题的答案 - “如果应用程序是 100% CPU 绑定 - 可能每个内核一个线程”。优秀。休息一下,我可以通过 CPU(系统和用户)使用率与空闲时间等对非 CPU 密集型应用程序进行基准测试。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 2016-08-07
    • 2011-05-15
    相关资源
    最近更新 更多