概念

Multi-Processing Module 多路处理模块

从Apache HTTP2.0开始。提供了可以选择的多处理模块,用来绑定到网络端口,接受请求,以及调度子进程处理请求。

httpd支持三种MPM工作模式:prefork、worker、event
在任何时间, 必须有一个,而且只有一个 MPM 加载到服务器中

MPM构建方式

构建为静态模块

只有在编译安装httpd的情况下,可以配置静态的MPM模块。
在所有的平台中,MPM都可以构建为静态模块。在构建时悬着一种MPM,连接到服务器中。如果要改编MPM,只能重新搭建httpd。为了使用指定的MPM,需要在执行configure脚本时,使用—with-mpm=NAME参数。NAME指的是MPM名称。编译安装完成后,可以使用httpd -M来确认加载的MPM。

构建为动态模块

在Unix和类Unix平台中,MPM可以构建为动态模块,与其它动态模块一样在运行时加载。构建MPM为动态模块的方法为修改LoadModule指令的内容来实现,不需要重新搭建httpd服务器程序。

LoadModule方式

  1. [root@apache ~]# cat /etc/httpd/conf.modules.d/00-mpm.conf
  2. # Select the MPM module which should be used by uncommenting exactly
  3. # one of the following LoadModule lines:
  4. # prefork MPM: Implements a non-threaded, pre-forking web server
  5. # See: http://httpd.apache.org/docs/2.4/mod/prefork.html
  6. #LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
  7. # worker MPM: Multi-Processing Module implementing a hybrid
  8. # multi-threaded multi-process web server
  9. # See: http://httpd.apache.org/docs/2.4/mod/worker.html
  10. #
  11. LoadModule mpm_worker_module modules/mod_mpm_worker.so
  12. # event MPM: A variant of the worker MPM with the goal of consuming
  13. # threads only for connections with active processing
  14. # See: http://httpd.apache.org/docs/2.4/mod/event.html
  15. #
  16. #LoadModule mpm_event_module modules/mod_mpm_event.so

如果httpd是通过源码编译安装的话,在执行configure脚本时,使用—enable-mpms-shared选项来启动动态特性,当给出all参数后,所有当前系统支持的MPM模块都会被安装,也可以在参数中给出想要安装的MPM模块列表。


prefork

概述

该多处理模块(MPM)实现了一个非线程的,预分支的Web服务器。每个服务器进程都可以回答传入的请求,并且父进程管理服务器池的大小。它适用于需要避免使用线程以与非线程安全库兼容的站点。这也是隔离每个请求的最佳MPM,因此单个请求的问题不会影响任何其他请求。

prefork的自我调节性很强,所以几乎不需要对配置项进行调整。MaxRequestWorkers的值应为系统希望接收的并发请求,但又应该足够小,以确保RAM能够其它进程的使用。

运行原理

单个父进程负责启动子进程,子进程监听连接到父进程端口并在接收到请求时为请求提供服务。httpd会预先派生好几个备用的空闲的子进程,用于随时可以处理传人的请求。客户端无需等待父进程派生出新的子进程,就可以满足用户的请求。

通常情况下,prefork的配置项不需要做自定义配置,其各个配置项的默认参数,足以结合自身的调节能力来满足用户的需求。
当服务器需要处理的并发量高于256时,需要调整MaxRequestWorkers选项大于256。
当服务器的内存空间非常有限的情况下,需要将MaxRequestWorkers选项调小。

在prefork工作模式下,httpd的父进程通常情况下是由root启动,以便于绑定80端口。子进程全部由apache用户启动。

配置项

  1. <IfModule prefork.c>
  2. ServerLimit 1500 #
  3. StartServers 5 #定义预发进程数
  4. MinSpareServers 5 #最小空闲进程
  5. MaxSpareServers 10 #最大空闲进程
  6. MaxClients 1000 #并发连接数
  7. ServerLimit 1500 #控制进程总数
  8. MaxRequestsPerChild 4000 #防止内存泄露,将其设为非零
  9. #当某个进程处理了4000个请求,就会自动关闭这个进程。
  10. #设置为大于0有好处:
  11. #1.能防止内存泄漏无限进行,从而耗尽内存。
  12. #2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。
  13. </IfModule>

image.png
性能

image.png

image.png


worker

概述

该模块混合了多进程与多线程。通过线程来处理请求,与基于进程来处理请求的服务器相比,它能够以较少的资源来处理大量的请求。但是,它通过保持多个可用进程来保留基于进程的线程的稳定性。

原理

单个父进程负责启动多个子进程。每个子进程会创建ThreadsPerChild中指定数量的固定的服务器线程数量,以及监听器线程,以监听连接并将连接到达时将其传递给服务器线程进行处理。

在worker工作模式下,httpd会始终保持一个备用子进程(线程池),用来随时为传入的请求提供服务。客户端无需等待新线程或进程的创建就可以为他们的请求提供服务。初始启动的进程数由StartServers 指令设置。在运行期间,服务器评估所有进程中空闲线程的总数,并分叉或终止进程,以使该数量保持在MinSpareThreads和所指定的范围内。MaxSpareThreads。由于此过程是非常自我调节的,因此几乎不需要从这些指令的默认值修改这些指令。可以同时服务的最大客户端数(即,所有进程中的最大线程总数)由MaxRequestWorkers指令确定 。活动子进程的最大数量由MaxRequestWorkers 指令除以ThreadsPerChild指令确定。
有两个指令对活动的子进程数和子进程中的服务器线程数设置了硬性限制,并且只能通过完全停止服务器然后再次启动服务器来更改。 ServerLimit是对活动子进程数的硬限制,并且必须大于或等于 MaxRequestWorkers 伪指令除以 ThreadsPerChild伪指令。 ThreadLimit是服务器线程数的硬限制,并且必须大于或等于ThreadsPerChild指令。
除了这组活动的子进程之外,可能还有其他子进程正在终止,但是其中至少有一个服务器线程仍在处理现有的客户端连接。MaxRequestWorkers尽管可以预期实际数量会小得多,但最多可能存在终止过程。可以通过禁用单个子进程的终止来避免此行为,这可以通过以下方式实现:
将值设置 MaxConnectionsPerChild为零
将的值设置 MaxSpareThreads为与相同的值 MaxRequestWorkers

配置项

  1. [root@apache conf.d]# cat mpm-worker.conf
  2. <IfModule worker.so>
  3. ServerLimit       32 #最大进程数
  4. ThreadLimit       128 #最大线程数
  5. StartServers      5 #服务启动时建立的子进程数量,默认为3
  6. MaxClients        2048 #最大并发连接数
  7. MinSpareThreads    150 #空闲子进程的最小数量
  8. MaxSpareThreads    500 #空闲子进程的最大数量
  9. ThreadsPerChild     64 #每个子进程产生的线程数量,默认为64
  10. MaxRequestsPerChild 2048 #MaxConnectionsPerChild
  11. #每个子进程在其生命周期内允许最大的请求数量,如果请求总数已经达到这个数值,子进程将会结束,
  12. 如果设置为0,子进程将永远不会结束。在Apache2.3.9之前称之为MaxRequestsPerChild
  13. </IfModule>

image.pngimage.png
image.png
image.png


event

概述