我在 Ubuntu Linux 下的 Apache2 服务器上发现了一些奇怪的事情。
我有两个网站,一个由 Apache2 通过 Passenger 模块直接处理(它是一个 ruby webapp),另一个反向代理到 Tomcat6 服务器的另一个端口。
一切似乎都很好,但是 Apache2 的行为似乎真的很贪婪:top
我看到它至少有 5-6 个进程,当我对这两个服务器发出一些请求时,它们会增加到 13-14 个。
有这么多工序正确吗?
如果没有必要,我是否应该将其配置得不那么贪婪?我将其与功能较弱的机器(512mb RAM vs 2gb RAM)上的类似配置进行了比较,似乎在这台机器上它保持的进程较少。也许 Apache2 对机器进行基准测试以了解要分配多少资源?
仅供参考,两台机器实际上都是在 VMWare 服务器下虚拟化的
提前致谢
答案1
你应该阅读Apache 文档处理多处理模块 (MPM)简而言之,这决定了 Apache 如何处理多个请求,主要有两种方法可以做到这一点:预分叉(这听起来就像你现在正在做的事情)和螺纹工人,这通常更有效率。
正如您所说,Prefork 会创建并维护许多“备用”Apache 进程,每个进程处理一个客户端。当进程不足时,Apache 会创建更多进程。这可能会很慢并且消耗大量内存。可以调整创建多少个进程使用启动服务器,最小备用服务器, 和最大备用服务器数配置指令。
Worker 使用单个或少量进程,但在每个进程内创建多个线程来处理每个请求。这样效率更高,但与某些非线程安全的 Apache 模块(最明显的是 PHP)不兼容。因此,如果您正在使用此类模块,则需要考虑切换到 FastCGI。
来自 Apache 文档:
Apache MPM 预分叉
此多处理模块 (MPM) 实现了非线程、预分叉的 Web 服务器,以类似于 Apache 1.3 的方式处理请求。它适用于需要避免线程以兼容非线程安全库的站点。它也是隔离每个请求的最佳 MPM,因此单个请求的问题不会影响其他请求。
[...]
单个控制进程负责启动子进程,这些子进程监听连接并在连接到达时提供服务。Apache 始终尝试维护多个备用或空闲的服务器进程,这些进程随时准备为传入请求提供服务。这样,客户端无需等待分叉出新的子进程即可为其请求提供服务。
StartServers、MinSpareServers、MaxSpareServers 和 MaxClients 控制父进程如何创建子进程来处理请求。一般来说,Apache 具有很强的自我调节能力,因此大多数站点不需要调整这些指令的默认值。需要处理超过 256 个同时请求的站点可能需要增加 MaxClients,而内存有限的站点可能需要减少 MaxClients 以防止服务器崩溃(将内存交换到磁盘并返回)。性能提示文档中提供了有关调整进程创建的更多信息。
和:
Apache MPM 工作器
此多处理模块 (MPM) 实现了混合多进程多线程服务器。通过使用线程来处理请求,它能够以比基于进程的服务器更少的系统资源来处理大量请求。然而,它通过保持多个进程可用(每个进程都有许多线程)保留了基于进程的服务器的大部分稳定性。
[...]
单个控制进程(父进程)负责启动子进程。每个子进程都会创建固定数量的服务器线程(如 ThreadsPerChild 指令中指定),以及一个侦听线程,用于侦听连接并在连接到达时将其传递给服务器线程进行处理。
我从mod_php和mpm_prefork到 FastCGI PHP 和mpm_worker,并发现性能大幅提升,尤其是静态文件(图像、HTML 文件等)。您的里程可能会有所不同...