Apache Prefork和Worker MPM的区别

124
查看Apache配置文件,我发现定义了Prefork和Worker MPM。它们的区别是什么?Apache正在使用哪一个?
8个回答

127

预派生(prefork)和工作线程(worker)是Apache提供的两种多进程模块(MPM),各有其优点和缺点。

默认情况下,Apache使用线程安全的预派生(Prefork) MPM。

预派生(Prefork) MPM使用多个具有一个线程的子进程,每个进程一次只能处理一个连接。

工作线程(Worker) MPM使用多个具有多个线程的子进程,每个线程一次只能处理一个连接。

有关更多详细信息,请访问https://httpd.apache.org/docs/2.4/mpm.htmlhttps://httpd.apache.org/docs/2.4/mod/prefork.html


14
请参考“我该如何选择使用哪种Apache MPM?”http://serverfault.com/a/383634 - Nazariy
@arvind //每个线程一次只处理一个连接// 这里的连接是指单个用户还是单个请求?请解释 - user1844933

23

Apache的多进程模块(MPMs)负责绑定机器上的网络端口,接受请求并分派子进程来处理请求(http://httpd.apache.org/docs/2.2/mpm.html)。

它们就像其他任何Apache模块一样,但是只能在服务器中加载一个且仅有一个MPM。MPMs在配置期间被选择并通过使用configure脚本的参数--with-mpm=NAME编译到服务器中,其中NAME是所需MPM的名称。

除非在编译时选择不同的MPM(例如在Windows上默认使用mpm_winnt),否则Apache将为每个操作系统使用默认的MPM。以下是操作系统及其默认MPM的列表:

  • BeOS beos
  • Netware mpm_netware
  • OS/2 mpmt_os2
  • Unix/Linux prefork (更新适用于Apache版本≥2.4:根据平台能力,使用preforkworkerevent)
  • Windows mpm_winnt

要检查编译到服务器中的模块,请使用命令行选项-l此处是文档)。例如,在Windows安装上,您可能会得到以下内容:

> httpd -l
Compiled in modules:
  core.c
  mod_win32.c
  mpm_winnt.c
  http_core.c
  mod_so.c

截至版本2.2,这是可用核心功能和MPM模块列表:
  • core - 始终可用的Apache HTTP Server核心功能
  • mpm_common - 由多个多处理模块(MPM)实现的指令集合
  • beos - 这个多处理模块针对BeOS进行了优化。
  • event - 标准工作进程MPM的实验变体
  • mpm_netware - 实现专门为Novell NetWare优化的纯线程Web服务器的多处理模块
  • mpmt_os2 - 用于OS/2的混合多进程、多线程MPM
  • prefork - 实现非线程化、预分叉Web服务器
  • mpm_winnt - 这个多处理模块针对Windows NT进行了优化。
  • worker - 实现混合多线程、多进程Web服务器的多处理模块
现在,我们来谈谈preforkworker之间的区别。 prefork MPM实现了一个非线程化、预先派生的Web服务器,以类似于Apache 1.3的方式处理请求。它适用于需要避免线程与不支持线程安全库的站点。它也是隔离每个请求的最佳MPM,因此单个请求的问题不会影响其他请求。请注意,保留了HTML标签。

worker MPM实现了一个混合的多进程多线程服务器,性能更好,因此应该优先使用,除非使用其他包含非线程安全库的模块(也请参见这个讨论这个在Serverfault上)。


1
一个默认安装的ubuntu-trusty-64上的apache 2.4.7正在使用事件MPM。 - Federico

9
请查看此链接以了解更多细节。它涉及Apache如何处理多个请求。默认情况下,使用Prefork模型,会启动一些Apache进程(在此处默认为2个,但我相信可以通过httpd.conf进行配置)。Worker MPM将为每个请求启动一个新线程,这可能更加节省内存。历史上,Apache一直使用Prefork模型,因此是经过更好测试的模型。线程只在2.0版本中添加。

4
事件(Event)多处理模块(MPM)如何? - secondman

6

对于CentOS 6.x和7.x(包括Amazon Linux),请使用:

sudo httpd -V

这将展示配置的MPM类型,包括Prefork、Worker或Event。Prefork是较早的线程安全模型,而Worker则支持多线程,Event支持php-mpm,该系统可更好地处理线程和请求。
但是,根据配置不同,您的结果可能会有所不同。我曾看到php-mpm有很多不稳定性,并没有提高速度。一个攻击性的爬虫可以很容易地耗尽php-mpm中的最大子进程数。
在CentOS 6.x/7.x/Apache 2.4中,Prefork,Worker或Event的设置在sudo nano /etc/httpd/conf.modules.d/00-mpm.conf中进行。
# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:

# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#LoadModule mpm_worker_module modules/mod_mpm_worker.so

# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#LoadModule mpm_event_module modules/mod_mpm_event.so

3
您可以通过输入以下命令来判断Apache是否使用preform或worker:
apache2ctl -l

在输出结果中,寻找prefork.c或worker.c的提及。

10
Apache可以使用两个MPM模块编译,因此这种方法并不总是可靠的。如果列出了两个MPM模块,请尝试使用apachectl -V命令,并查看Server MPM旁边的输出。您还可以使用ps aux命令,并查找httpdhttpd.worker - reflexiv
3
在我的情况下,apache2ctl -l 不起作用;必须使用 apachectl -l - Vacilando
2
没有一个列出来是我的,但Apache运行良好,Apache/2.4.7 (Ubuntu)。 - karatedog
2
在运行 Apache 2.4.6 的 CentOS 7.x 中,httpd -V 命令将会返回类似以下内容:Server MPM: worker - runamok

2

在RHEL7上,Apache 2.4之间切换prefork或worker mpm非常容易。

通过执行以下命令检查MPM类型:

sudo httpd -V

Server version: Apache/2.4.6 (Red Hat Enterprise Linux)
Server built:   Jul 26 2017 04:45:44
Server's Module Magic Number: 20120211:24
Server loaded:  APR 1.4.8, APR-UTIL 1.5.2
Compiled using: APR 1.4.8, APR-UTIL 1.5.2
Architecture:   64-bit
Server MPM:     prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=256
 -D HTTPD_ROOT="/etc/httpd"
 -D SUEXEC_BIN="/usr/sbin/suexec"
 -D DEFAULT_PIDLOG="/run/httpd/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"

现在要更改MPM,请编辑以下文件并取消所需的MPM注释。
 /etc/httpd/conf.modules.d/00-mpm.conf 

# Select the MPM module which should be used by uncommenting exactly
# one of the following LoadModule lines:

# prefork MPM: Implements a non-threaded, pre-forking web server
# See: http://httpd.apache.org/docs/2.4/mod/prefork.html
LoadModule mpm_prefork_module modules/mod_mpm_prefork.so

# worker MPM: Multi-Processing Module implementing a hybrid
# multi-threaded multi-process web server
# See: http://httpd.apache.org/docs/2.4/mod/worker.html
#
#LoadModule mpm_worker_module modules/mod_mpm_worker.so

# event MPM: A variant of the worker MPM with the goal of consuming
# threads only for connections with active processing
# See: http://httpd.apache.org/docs/2.4/mod/event.html
#
#LoadModule mpm_event_module modules/mod_mpm_event.so

为什么当我尝试使用mpm_worker或mpm_event时,我的页面无法工作? - Leoh

1

Apache有两种MPM(多处理模块):

1:Prefork 2:Worker

默认情况下,Apacke以预派生的模式进行配置,即非线程化的预派生Web服务器。这意味着每个Apache子进程包含单个线程并一次处理一个请求。因此,它消耗更多资源。

Apache还有worker MPM,它将Apache转换为多进程、多线程的Web服务器。Worker MPM使用多个带有多个线程的子进程。


0
首先检查正在运行的模块:-
如果您正在配置Ubuntu/Debian:-
sudo apachectl -M | grep 'mpm'
vi /etc/apache2/mods-available/mpm_prefork.conf

..

.. 启动服务器数量 8

.. 最小空闲服务器数量 20

.. 最大空闲服务器数量 40

.. 最大请求工作进程数量 200

.. 每个子进程最大连接数 4500

..

使用apachectl -t进行语法检查或apachectl configtest

如果你想在worker或event中进行相同的更改,则:-

/etc/apache2/mods-available/mpm_event.conf

在不同的模块中进行更改后,您需要切换模块。 如果您正在使用事件模块并希望更改为Prefork模块:-
禁用事件模块:a2dismod mpm_event
启用Prefork模块:a2enmod mpm_event
然后重新启动Apache:service apache2 restart
如果是httpd(在redhat、centos等上配置)
首先检查运行的模块:httpd -V | grep -i 'mpm'
vi /etc/httpd/conf.modules.d/00-mpm.conf
取消注释prefork模块行(LoadModule mpm_prefork_module modules/mod_mpm_prefork.so):LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
如果要更改其他模块,则取消注释该模块行(事件或工作线程)和其他注释
httpd -t进行语法检查
现在启动Apache服务:systemctl restart httpd
但有时在更改mpm模块之前会出现php模块错误,然后进行完整的教程和计算。

https://www.youtube.com/watch?v=8V4TFgFvurU&list=PL5gKsZrSyQQIBNOTLGedvzlKLD9hKoTmS&index=10


你的回答可以通过提供更多支持性信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人能够确认你的回答是否正确。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - Community

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接