免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 7331 | 回复: 18
打印 上一主题 下一主题

apache20++mpm工作方式探讨V1.0版(最后更新:Oct 30) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-10-29 14:22 |只看该作者 |倒序浏览
作者:Alson Black,BestWC

Hack0Nux Core Team -> Oct 30, 2007
Email:FreeAlson_at_Gmail.CoM

版权说明:本文为自由文章,任何人可以随意转载,不受限制。


引言:
-------------------偶是分割线-------------------
    对于使用BSD架站的人来说,选择一款优秀的WEB服务组件是第一个问题--在apache盛行的今天,如果你不幸选择了它作为WEB服务组件并且更加不幸得选择了apache20以上的版本--接下来的问题是:选择什么样的工作方式?
    坛子上经常能看到有人发贴询问为什么apache工作效率低,该如何优化?而不巧的是Unix-Like方面的application信息非常少,同样仅有的那些也非常之杂。而解决这些问题正是本贴的目的,通过大家的共同讨论和分享自己的实战经验为每一种mpm工作方式进行正确的评价以避免在以后更加复杂的应用环境下为选择mpm而绞尽脑汁.
------------------------------------------------

什么是mpm:
-------------------偶是分割线-------------------   

MPM(Multi -Processing Modules,多路处理模块)是Apache2.0中影响性能的最核心特性。是Apache 2.x才支持的一个可插入的并发模型,在编译的时候,我们只可以选择一个并发模型
格式
–with-mpm=MPM Choose the process model for Apache to use.
MPM={beos|worker|prefork|mpmt_os2| perchild|leader|threadpool}

1、Beos、mpmt_os2分别是BeOS和OS/2上缺省的MPM

2、perchild主要设计目的是以不同的用户和组的身份来运行不同的子进程.这在运行多个需要CGI的虚拟主机时特别有用,会比1.3版中的SuExec 机制做得更好.

3、leader和threadpool都是基于worker的变体,还处于实验性阶段,某些情况下并不会按照预期设想的那样工作,所以 Apache官方也并不推荐使用.

4、prefork如果不用“–with-mpm”显式指定某种MPM,prefork就是LInux/Unix平台上缺省的MPM.它所采用的预派生子进程方式也是 Apache 1.3中采用的模式.prefork本身并没有使用到线程,2.0版使用它是为了与1.3版保持兼容性;另一方面,prefork用单独的子进程来处理不同的请求,进程之间是彼此独立的,这也使其成为最稳定的MPM之一.
   prefork的工作原理是,控制进程在最初建立“StartServers”个子进程后,为了满足MinSpareServers设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足 MinSpareServers设置的值为止.这就是预派生(prefork)的由来.这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能.

5、worker相对于prefork,worker是2.0 版中全新的支持多线程和多进程混合模型的MPM.由于使用线程来处理,所以可以处理相对海量的请求,而系统资源的开销要小于基于进程的服务器.但是, worker也使用了多进程,每个进程又生成多个线程,以获得基于进程服务器的稳定性.这种MPM的工作方式将是Apache 2.0的发展趋势.
   worker的工作原理是,由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild 线程数,各个线程独立地处理请求.同样,为了不在请求到来时再生成线程,MinSpareThreads和MaxSpareThreads设置了最少和最多的空闲线程数;而MaxClients设置了所有子进程中的线程总数.如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程.

------------------------------------------------

目前都有哪些工作方式:
-------------------偶是分割线-------------------
从上文可以看出目前支持的主流工作方式:
1、Beos、mpmt_os2
2、perchild
3、leader和threadpool
4、prefork
5、worker
因为此文对BSD系统的针对性,我们将不讨论与beos\mpmt_os2有关的内容.根据官方的发言,leader和threadpool工作方式在目前引入生产环境是十分不理智的,在讨论工作效率和稳定性的本文中,我们也将省略这部分内容.鉴于时效性的考虑,perchild的工作方式我们也许会在今后谈到.
那么接下来的问题就变的很简单了,我们只需要讨论2种工作方式:
prefork 和 代表着apache未来发展动向的worker.
------------------------------------------------
引入mpm的好处:
-------------------偶是分割线-------------------
Apache 2.0在性能上的改善最吸引人。在支持POSIX线程的Unix系统上,Apache可以通过不同的MPM运行在一种多进程与多线程相混合的模式下,增强部分配置的可扩充性能。相比于Apache 1.3,2.0版本做了大量的优化来提升处理能力和可伸缩性,并且大多数改进在默认状态下即可生效。但是在编译和运行时刻,2.0也有许多可以显著提高性能的选择。

  毫不夸张地说,MPM的引入是Apache 2.0最重要的变化。大家知道,Apache是基于模块化的设计,而Apache 2.0更扩展了模块化设计到Web服务器的最基本功能。服务器装载了一种多道处理模块,负责绑定本机网络端口、接受请求,并调度子进程来处理请求。扩展模块化设计有两个重要好处:

  ◆ Apache可以更简洁、有效地支持多种操作系统;

  ◆ 服务器可以按站点的特殊需要进行自定制。

------------------------------------------------

[ 本帖最后由 bestwc 于 2007-10-30 09:23 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2007-10-29 14:24 |只看该作者
OK,了解了这么多信息,我们该着重分别讨论本文议题的重点:两种"性格"迥异的工作方式.

Part.1 All About Perfork
-------------------偶是分割线-------------------
首先来一份官方的说明文档:
http://lamp.linux.gov.cn/Apache/ApacheMenu/mod/prefork.html
Apache MPM prefork
说明一个非线程型的、预派生的MPM状态MPM
模块名mpm_prefork_module
源文件prefork.c
概述 这个多路处理模块(MPM)实现了一个非线程型的、预派生的web服务器,它的工作方式类似于Apache 1.3。它适合于没有线程安全库,需要避免线程兼容性问题的系统。它是要求将每个请求相互独立的情况下最好的MPM,这样若一个请求出现问题就不会影响到其他请求。
这个MPM具有很强的自我调节能力,只需要很少的配置指令调整。最重要的是将MaxClients设置为一个足够大的数值以处理潜在的请求高峰,同时又不能太大,以致需要使用的内存超出物理内存的大小。


工作方式
一个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并作出应答。Apache总是试图保持一些备用的(spare)或者是空闲的子进程用于迎接即将到来的请求。这样客户端就不需要在得到服务前等候子进程的产生。
StartServers, MinSpareServers, MaxSpareServers, MaxClients指令用于调节父进程如何产生子进程。通常情况下Apache具有很强的自我调节能力,所以一般的网站不需要调整这些指令的默认值。可能需要处理最大超过256个并发请求的服务器可能需要增加MaxClients的值。内存比较小的机器则需要减少MaxClients的值以保证服务器不会崩溃。更多关于调整进程产生的问题请参见性能方面的提示
在Unix系统中,父进程通常以root身份运行以便邦定80端口,而Apache产生的子进程通常以一个低特权的用户运行。UserGroup指令用于设置子进程的低特权用户。运行子进程的用户必须要对它所服务的内容有读取的权限,但是对服务内容之外的其他资源必须拥有尽可能少的权限。
MaxRequestsPerChild指令控制服务器杀死旧进程产生新进程的频率。


MaxSpareServers 指令
说明空闲子进程的最大数量语法MaxSpareServers number默认值MaxSpareServers 10作用域server config状态MPM模块prefork
MaxSpareServers指令
设置空闲子进程的最大数量。所谓空闲子进程是指没有正在处理请求的子进程。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。
只有在非常繁忙机器上才需要调整这个参数。将此参数设的太大通常是一个坏主意。如果你将该指令的值设置为比MinSpareServers小,Apache将会自动将其修改成"MinSpareServers+1"。
参见


MinSpareServers 指令
说明空闲子进程的最小数量语法MinSpareServers number默认值MinSpareServers 5作用域server config状态MPM模块prefork

MinSpareServers指令设置空闲子进程的最小数量。所谓空闲子进程是指没有正在处理请求的子进程。如果当前空闲子进程数少于MinSpareServers ,那么Apache将以最大每秒一个的速度产生新的子进程。
只有在非常繁忙机器上才需要调整这个参数。将此参数设的太大通常是一个坏主意。
参见

[ 本帖最后由 bestwc 于 2007-10-29 14:38 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2007-10-29 14:25 |只看该作者
个人认为在这篇官方文档中我们需要注意下面几个地方:
1,它的工作方式类似于Apache 1.3
2,它是要求将每个请求相互独立的情况下最好的MPM
3,最重要的是将MaxClients设置为一个足够大的数值以处理潜在的请求高峰
4,Apache总是试图保持一些备用的(spare)或者是空闲的子进程用于迎接即将到来的请求
5,一般的网站不需要调整这些指令的默认值
6,可能需要处理最大超过256个并发请求的服务器可能需要增加MaxClients的值
7,Apache产生的子进程通常以一个低特权的用户运行
8,MaxRequestsPerChild指令控制服务器杀死旧进程产生新进程的频率

好了,下面我们一起设置一下perfoke的mpm,共同讨论这些选项的配置问题.
以下内容来自FreeBSD系统ports方式安装的apache22位于/usr/local/etc/apache22/extra/httpd-mpm.conf文件:
# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule mpm_prefork_module>
    StartServers          5
    MinSpareServers       5
    MaxSpareServers      10
    MaxClients          150
    MaxRequestsPerChild   0
</IfModule>

1,StartServers: number of server processes to start
StartServers指令
说明服务器启动时建立的子进程数
语法StartServers number
默认值参见下面的说明
作用域server config
状态MPM
模块mpmt_os2, prefork, worker
StartServers指令设置了服务器启动时建立的子进程数量。因为子进程数量动态的取决于负载的轻重,所有一般没有必要调整这个参数。
不同的MPM默认值也不一样。对于worker默认值是"3"。对于prefork默认值是"5",mpmt_os2是"2"。

2,MinSpareServers: minimum number of server processes which are kept spare

MinSpareServers指令
说明空闲子进程的最小数量
语法MinSpareServers number
默认值MinSpareServers 5
作用域server config
状态MPM
模块prefork
MinSpareServers指令设置空闲子进程的最小数量。所谓空闲子进程是指没有正在处理请求的子进程。如果当前空闲子进程数少于MinSpareServers ,那么Apache将以最大每秒一个的速度产生新的子进程。
只有在非常繁忙机器上才需要调整这个参数。将此参数设的太大通常是一个坏主意。
参见

3,MaxSpareServers: maximum number of server processes which are kept spare

MaxSpareServers指令
说明空闲子进程的最大数量
语法MaxSpareServers number
默认值MaxSpareServers 10
作用域server config
状态MPM
模块prefork
MaxSpareServers指令设置空闲子进程的最大数量。所谓空闲子进程是指没有正在处理请求的子进程。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。
只有在非常繁忙机器上才需要调整这个参数。将此参数设的太大通常是一个坏主意。如果你将该指令的值设置为比MinSpareServers小,Apache将会自动将其修改成"MinSpareServers+1"。
参见

4,MaxClients: maximum number of server processes allowed to start

MaxClients 指令
说明允许同时伺服的最大接入请求数量
语法MaxClients number
默认值参见下面的说明
作用域server config
状态MPM
模块beos, prefork, worker
MaxClients指令设置了允许同时伺服的最大接入请求数量。任何超过MaxClients限制的请求都将进入等候队列,直到达到ListenBacklog指令限制的最大值为止。一旦一个链接被释放,队列中的请求将得到服务。
对于非线程型的MPM(也就是prefork),MaxClients表示可以用于伺服客户端请求的最大子进程数量,默认值是256。要增大这个值,你必须同时增大ServerLimit
对于线程型或者混合型的MPM(也就是beosworker),MaxClients表示可以用于伺服客户端请求的最大线程数量。线程型的beos的默认值是50。对于混合型的MPM默认值是16(ServerLimit)乘以25(ThreadsPerChild)的结果。因此要将MaxClients增加到超过16个进程才能提供的时候,你必须同时增加ServerLimit的值。

5,MaxRequestsPerChild: maximum number of requests a server process serves

MaxRequestsPerChild指令
说明每个子进程在其生存期内允许伺服的最大请求数量
语法MaxRequestsPerChild number
默认值MaxRequestsPerChild 10000
作用域server config
状态MPM
模块mpm_netware, mpm_winnt, mpmt_os2, prefork, worker
MaxRequestsPerChild指令设置每个子进程在其生存期内允许伺服的最大请求数量。到达MaxRequestsPerChild的限制后,子进程将会结束。如果MaxRequestsPerChild为"0",子进程将永远不会结束。
不同的默认值在mpm_netwarempm_winnt上的默认值是"0"。

MaxRequestsPerChild设置成非零值有两个好处:

  • 可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
  • 给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。
注意对于KeepAlive链接,只有第一个请求会被计数。事实上,它改变了每个子进程限制最大链接数量的行为。

OK,看过官方的说明后我们一起来看看用户的实战经验是怎么说的(注意以下内容仅供参考):

  prefork的工作原理及配置

  如果不用“--with-mpm”显式指定某种MPM,prefork就是Unix平台上缺省的MPM。它所采用的预派生子进程方式也是 Apache 1.3中采用的模式。prefork本身并没有使用到线程,2.0版使用它是为了与1.3版保持兼容性;另一方面,prefork用单独的子进程来处理不同的请求,进程之间是彼此独立的,这也使其成为最稳定的MPM之一。

  若使用prefork,在make编译和make install安装后,使用“httpd -l”来确定当前使用的MPM,应该会看到prefork.c(如果看到worker.c说明使用的是worker MPM,依此类推)。再查看缺省生成的httpd.conf配置文件,里面包含如下配置段:

<IfModule prefork.c>;
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 150
MaxRequestsPerChild 0
</IfModule>;



  prefork的工作原理是,控制进程在最初建立“StartServers”个子进程后,为了满足MinSpareServers设置的需要创建一个进程,等待一秒钟,继续创建两个,再等待一秒钟,继续创建四个……如此按指数级增加创建的进程数,最多达到每秒32个,直到满足 MinSpareServers设置的值为止。这就是预派生(prefork)的由来。这种模式可以不必在请求到来时再产生新的进程,从而减小了系统开销以增加性能。

  MaxSpareServers设置了最大的空闲进程数,如果空闲进程数大于这个值,Apache会自动kill掉一些多余进程。这个值不要设得过大,但如果设的值比MinSpareServers小,Apache会自动把其调整为MinSpareServers+1。如果站点负载较大,可考虑同时加大MinSpareServers和MaxSpareServers。

  MaxRequestsPerChild设置的是每个子进程可处理的请求数。每个子进程在处理了“MaxRequestsPerChild” 个请求后将自动销毁。0意味着无限,即子进程永不销毁。虽然缺省设为0可以使每个子进程处理更多的请求,但如果设成非零值也有两点重要的好处:

  ◆ 可防止意外的内存泄漏;

  ◆ 在服务器负载下降的时侯会自动减少子进程数。

  因此,可根据服务器的负载来调整这个值。笔者认为10000左右比较合适。

  MaxClients是这些指令中最为重要的一个,设定的是Apache可以同时处理的请求,是对Apache性能影响最大的参数。其缺省值 150是远远不够的,如果请求总数已达到这个值(可通过ps -ef|grep http|wc -l来确认),那么后面的请求就要排队,直到某个已处理请求完毕。这就是系统资源还剩下很多而HTTP访问却很慢的主要原因。系统管理员可以根据硬件配置和负载情况来动态调整这个值。虽然理论上这个值越大,可以处理的请求就越多,但Apache默认的限制不能大于256。如果把这个值设为大于256,那么 Apache将无法起动。事实上,256对于负载稍重的站点也是不够的。在Apache 1.3中,这是个硬限制。如果要加大这个值,必须在“configure”前手工修改的源代码树下的src/include/httpd.h中查找 256,就会发现“#define HARD_SERVER_LIMIT 256”这行。把256改为要增大的值(如4000),然后重新编译Apache即可。在Apache 2.0中新加入了ServerLimit指令,使得无须重编译Apache就可以加大MaxClients。下面是笔者的prefork配置段:

<IfModule prefork.c>
StartServers 10
MinSpareServers 10
MaxSpareServers 15
ServerLimit 2000
MaxClients 1000
MaxRequestsPerChild 10000
</IfModule>

本人建议:
1,可视服务器负载的轻重来调整StartServers,正如官方文档中所说的,如果我们没有特殊需求,不需要更改这个值,默认的5已经能满足大部分人的需求了.
2,对于MinSpareServers 和 MaxSpareServers你需要算一笔账了.MaxRequestsPerChild决定了每自进程接收到多少请求后被杀掉,假设StartServers的值为5,根据perfoke的指数级线程增长机制,MaxSpareServers*MaxRequestsPerChild便是服务器线程峰值的处理请求能力.当然这并不完全准确,但完全可以作为一个可行的参考.
3,对于MaxClients的更改需要非常慎重,你可以采取ps -ef|grep http|wc -l的"偏方"来查看你的应用环境对于这一参数的要求,当然,改动系统源代码来增大这一值的行为被认为是非常不理智的,在你确实感觉因为此参数而导致运行效率低下时可以尝试稍微增大此值并观察效果,直到调整为一恰当的值.
4,正如官方文档中所说的,MaxRequestsPerChild的值如果非零是很有好处的,而在默认安装的apache22中此值的默认值为0,所以如果你决心想做点什么优化的话,加大这个值通常是一个明智的选择,但同样的问题是,盲目的加大任何一个选项的值都是不理智的行为.
------------------------------------------------

[ 本帖最后由 bestwc 于 2007-10-29 14:46 编辑 ]

论坛徽章:
0
4 [报告]
发表于 2007-10-29 14:26 |只看该作者
Part.2 All About Worker
-----------偶是分割线-----------
老规矩,先来看一分官方文档:

Apache MPM worker
说明
支持混合的多线程多进程的多路处理模块
状态MPM
模块名mpm_worker_module
源文件worker.c
概述
此多路处理模块(MPM)使网络服务器支持混合的多线程多进程。由于使用线程来处理请求,所以可以处理海量请求,而系统资源的开销小于基于进程的MPM。但是,它也使用了多进程,每个进程又有多个线程,以获得基于进程的MPM的稳定性。
控制这个MPM的最重要的指令是,控制每个子进程允许建立的线程数的ThreadsPerChild指令,和控制允许建立的总线程数的MaxClients指令。


工作方式
每个进程可以拥有的线程数量是固定的。服务器会根据负载情况增加或减少进程数量。一个单独的控制进程(父进程)负责子进程的建立。每个子进程可以建立ThreadsPerChild数量的服务线程和一个监听线程,该监听线程监听接入请求并将其传递给服务线程处理和应答。

Apache总是试图维持一个备用(spare)或是空闲的服务线程池。这样,客户端无须等待新线程或新进程的建立即可得到处理。初始化时建立的进程数量由StartServers指令决定。随后父进程检测所有子进程中空闲线程的总数,并新建或结束子进程使空闲线程的总数维持在MinSpareThreadsMaxSpareThreads所指定的范围内。由于这个过程是自动调整的,几乎没有必要修改这些指令的缺省值。可以并行处理的客户端的最大数量取决于MaxClients指令。活动子进程的最大数量取决于MaxClients除以ThreadsPerChild的值。

有两个指令设置了活动子进程数量和每个子进程中线程数量的硬限制。要想改变这个硬限制必须完全停止服务器然后再启动服务器(直接重启是不行的),ServerLimit是活动子进程数量的硬限制,它必须大于或等于MaxClients除以ThreadsPerChild的值。ThreadLimit是所有服务线程总数的硬限制,它必须大于或等于ThreadsPerChild指令。这两个指令必须出现在其他workerMPM指令的前面。

在设置的活动子进程数量之外,还可能有额外的子进程处于"正在中止"的状态但是其中至少有一个服务线程仍然在处理客户端请求,直到到达MaxClients以致结束进程,虽然实际数量会很小。这个行为能够通过以下禁止特别的子进程中止的方法来避免:

一个典型的针对workerMPM的配置如下:
ServerLimit 16
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25


在Unix中,为了能够绑定80端口,父进程一般都是以root身份启动,随后,Apache以较低权限的用户建立子进程和线程。UserGroup指令用于设置Apache子进程的权限。虽然子进程必须对其提供的内容拥有读权限,但应该尽可能给予它较少的特权。另外,除非使用了suexec ,否则,这些指令设置的权限将被CGI脚本所继承。
MaxRequestsPerChild指令用于控制服务器建立新进程和结束旧进程的频率。


OK,接下来就一起总结下官方文档中需要注意的地方:
1,混合的多线程多进程
2,Apache总是试图维持一个备用(spare)或是空闲的服务线程池
3,由于这个过程是自动调整的,几乎没有必要修改这些指令的缺省值(指父进程创建子进程的过程)
4,要想改变这个硬限制必须完全停止服务器然后再启动服务器(直接重启是不行的),ServerLimit是活动子进程数量的硬限制,它必须大于或等于MaxClients除以ThreadsPerChild的值
5,ThreadLimit是所有服务线程总数的硬限制,它必须大于或等于ThreadsPerChild指令
6,在Unix中,为了能够绑定80端口,父进程一般都是以root身份启动,随后,Apache以较低权限的用户建立子进程和线程
7,除非使用了suexec ,否则,这些指令设置的权限将被CGI脚本所继承

一起来看看位于/usr/local/etc/apache22/extra/httpd-mpm.conf中的worker配置段:
(注意:以下内容已经过修改,非默认值)
# worker MPM
# StartServers: initial number of server processes to start
# MaxClients: maximum number of simultaneous client connections
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule mpm_worker_module>
    StartServers          5
    ServerLimit        3000
    MaxClients         5000
    MinSpareThreads      75
    MaxSpareThreads     300
    ThreadsPerChild      50
    MaxRequestsPerChild 80000
</IfModule>

1,StartServers: initial number of server processes to start
关于这个参数在上文已经讨论过了,这里我们需要注意的就是
根据官方文档“对于worker默认值是"3"。对于prefork默认值是"5"”
根据Worker的工作方式,预创建3个子进程来创建线程,“并新建或结束子进程使空闲线程的总数维持在MinSpareThreadsMaxSpareThreads所指定的范围内”,所以我们可以明显看出和Perfoke方式不同的是,我们基本没有必要更改这个参数的默认值,对于一个会根据负载自动调整范围参数我们不会指望给它一个很大的初始值会带来怎样的效率提升。

2,MaxClients: maximum number of simultaneous client connections
&&ServerLimit
官方文档中特别指明此参数在调整Worker工作效率方面作用非凡。这里有几个关于它的公式,当然非常烦琐和枯燥,不过正是这些枯燥乏味的东西构成了眼前激情无限的生活(啊,世界真是一个充满矛盾的大坩埚啊!)因为MaxClients和ServerLimit之间的联系,这里把它们放在一起讨论。MaxClients已经在前面介绍过了,这里补充一下ServerLimit的官方说明:



ServerLimit指令
说明服务器允许配置的进程数上限
语法ServerLimit number
默认值参见下面的说明
作用域server config
状态MPM
模块 prefork, worker
对于preforkMPM,这个指令设置了MaxClients最大允许配置的数值。对于workerMPM,这个指令和ThreadLimit结合使用设置了MaxClients最大允许配置的数值。任何在重启期间对这个指令的改变都将被忽略,但对MaxClients的修改却会生效。
使用这个指令时要特别当心。如果将ServerLimit设置成一个高出实际需要许多的值,将会有过多的共享内存被分配。如果将ServerLimitMaxClients设置成超过系统的处理能力,Apache可能无法启动,或者系统将变得不稳定。
对于preforkMPM,只有在你需要将MaxClients设置成高于默认值256的时候才需要使用这个指令。要将此指令的值保持和MaxClients一样。
对于workerMPM,只有在你需要将MaxClientsThreadsPerChild设置成需要超过默认值16个子进程的时候才需要使用这个指令。不要将该指令的值设置的比MaxClients ThreadsPerChild需要的子进程数量高。
注意Apache在编译时内部有一个硬限制"ServerLimit 20000"(对于preforkMPM为"ServerLimit 200000")。你不能超越这个限制。

参见


    1),MaxClients决定可以处理的客户端的最大数量。
    2),活动子进程的最大数量取决于
MaxClients除以ThreadsPerChild的值。
           即
MaxClients/ThreadsPerChild=ActiveThreads
    3),
ServerLimit是活动子进程数量的硬限制,它必须大于或等于MaxClients除以ThreadsPerChild的值
           即 ServerLimit Controls ActiveThreads
           And ServerLimit >=
MaxClients/ThreadsPerChild
       So ServerLimit >= ActiveThreads
  4),   需要注意的是,如果显式声明了ServerLimit,那么它乘以ThreadsPerChild的值必须大于等于MaxClients
      其实这是和各位玩的一个数字游戏,不过它对于检查你的设置是否合理很有用,打个比方。
      a/b <= c 所以 c* b >= a
      即 ServerLimit * ThreadsPerChild >= MaxClients
  5),MaxClients必须是ThreadsPerChild的整数倍
      即 MaxClients % ThreadsPerChild = 0
      这样规定的原因是如果一旦上面的等式不成立,那么ServerLimit >= MaxClients/ThreadsPerChild的等
      式也会出现问题,这样一来会导致ApaChe将其中的某个值自动调整成一个我们并不期望的值,这显然是
      违背我们的初衷的。


最后有一个非常重要的问题,在官方文档定义为“硬性限制”的两个参数,如果你需要定义它们,那它们的位置必须出现在其他Worker参数的前面。即ThreadLimit和ServerLimit必须在配置文件的前两行。

3,MinSpareThreads&&MaxSpareThreads
这些前面也已经讲得很清楚了,而且因为Woker方式的自动调节机制,我们对于这两个值不需要做过多的讨论,只需要注意它们控制着子进程创建的线程数量而已。

4,ThreadsPerChild: constant number of worker threads in each server process
这个参数对于Worker的工作方式也是非常有影响的,首先它的功能是“每个子进程可以建立ThreadsPerChild数量的服务线程和一个监听线程,该监听线程监听接入请求并将其传递给服务线程处理和应答。”也就是说这个参数直接决定了apache的负载能力。具体表现为ThreadsPerChild * StartServers = Worker方式所能同时处理的请求。
和前面perfoke中的参数处理一样,此值虽然对性能有决定性的影响,但盲目的增大这个值甚至通过更改源代码达到提高硬性限制的目的的行为是非常缺乏理智的。在没有积累到足够的经验前,这样的参数我们应该逐步增大并观察效果,直到将它和与它关系密切的参数调整为一适合的值为止。

5,MaxRequestsPerChild: maximum number of requests a server process serves
每个线程在处理多少请求后没杀掉。同样的一个温和参数,对于性能的影响并不大,但需要注意将它保持在一个适当的范围内。
MaxRequestsPerChild指令用于控制服务器建立新进程和结束旧进程的频率。”
----------------------------------


[ 本帖最后由 bestwc 于 2007-10-30 02:11 编辑 ]

论坛徽章:
0
5 [报告]
发表于 2007-10-29 14:26 |只看该作者
大概浏览过官方文档后我们关注一下个人实际应用中的经验:(注意以下内容仅供参考)
  worker的工作原理及配置

  相对于prefork,worker是2.0 版中全新的支持多线程和多进程混合模型的MPM。由于使用线程来处理,所以可以处理相对海量的请求,而系统资源的开销要小于基于进程的服务器。但是, worker也使用了多进程,每个进程又生成多个线程,以获得基于进程服务器的稳定性。这种MPM的工作方式将是Apache 2.0的发展趋势。

  在configure -with-mpm=worker后,进行make编译、make install安装。在缺省生成的httpd.conf中有以下配置段:

<IfModule worker.c>;
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>;



  worker的工作原理是,由主控制进程生成“StartServers”个子进程,每个子进程中包含固定的ThreadsPerChild 线程数,各个线程独立地处理请求。同样,为了不在请求到来时再生成线程,MinSpareThreads和MaxSpareThreads设置了最少和最多的空闲线程数;而MaxClients设置了所有子进程中的线程总数。如果现有子进程中的线程总数不能满足负载,控制进程将派生新的子进程。

  MinSpareThreads和MaxSpareThreads的最大缺省值分别是75和250。这两个参数对Apache的性能影响并不大,可以按照实际情况相应调节。

  ThreadsPerChild是worker MPM中与性能相关最密切的指令。ThreadsPerChild的最大缺省值是64,如果负载较大,64也是不够的。这时要显式使用 ThreadLimit指令,它的最大缺省值是20000。上述两个值位于源码树server/mpm/worker/worker.c中的以下两行:

#define DEFAULT_THREAD_LIMIT 64
#define MAX_THREAD_LIMIT 20000



  这两行对应着ThreadsPerChild和ThreadLimit的限制数。最好在configure之前就把64改成所希望的值。注意,不要把这两个值设得太高,超过系统的处理能力,从而因Apache不起动使系统很不稳定。

  Worker模式下所能同时处理的请求总数是由子进程总数乘以ThreadsPerChild值决定的,应该大于等于MaxClients。如果负载很大,现有的子进程数不能满足时,控制进程会派生新的子进程。默认最大的子进程总数是16,加大时也需要显式声明ServerLimit(最大值是20000)。这两个值位于源码树server/mpm/worker/worker.c中的以下两行:

#define DEFAULT_SERVER_LIMIT 16
#define MAX_SERVER_LIMIT 20000



  需要注意的是,如果显式声明了ServerLimit,那么它乘以ThreadsPerChild的值必须大于等于MaxClients,而且MaxClients必须是ThreadsPerChild的整数倍,否则Apache将会自动调节到一个相应值(可能是个非期望值)。下面是笔者的 worker配置段:

<IfModule worker.c>;
StartServers 3
MaxClients 2000
ServerLimit 25
MinSpareThreads 50
MaxSpareThreads 200
ThreadLimit 200
ThreadsPerChild 100
MaxRequestsPerChild 0
</IfModule>;


本人建议:
1,在我们整个分析过程中已经看出部分perfoke和worker间的区别,这个区别在StartServers和MaxRequestsPerChild及MinRequestsPerChild表现得十分明显,在perfoke中启决定性因素的参数因为worker的自动调节能力而变的不那么重要了。所以建议这3个参数的值保持默认并适当增加。
2,根据官方文档中说了“在设置的活动子进程数量之外,还可能有额外的子进程处于"正在中止"的状态但是其中至少有一个服务线程仍然在处理客户端请求,直到到达MaxClients以致结束进程”,处理这种问题的建议是
    1),将MaxRequestsPerChild的值设为0
    2),将MaxSpareThreadsMaxClients设为相同的值
这里如果你决心要处理掉这个并不十分打紧的问题的话,我推荐使用第二种方法。对于MaxRequestsPerChild设置为一个非零的值是比较明确的做法。
3,与perfoke相同的问题是,子进程由ROOT创建,而子进程创建的线程的属主可以使用User和Group指令设定。这里需要注意的是,如果你要DIY这个参数,请将User和Group在系统其他资源的访问上做好足够的限制。
4,注意那5个关于MaxClients的公式。
--------------------------------------

[ 本帖最后由 bestwc 于 2007-10-30 09:16 编辑 ]

论坛徽章:
0
6 [报告]
发表于 2007-10-29 14:27 |只看该作者
意见征集中,希望各位有相关经验的朋友共享自己对perfoke或worker的认识,共同完善此帖。

[ 本帖最后由 bestwc 于 2007-10-30 09:17 编辑 ]

论坛徽章:
0
7 [报告]
发表于 2007-10-29 14:38 |只看该作者
好文章,个人认为也是有必要讨论的一个话题...
针对apache方面,可以学习的太多...

论坛徽章:
0
8 [报告]
发表于 2007-10-29 15:08 |只看该作者
感谢支持,开个帖子大家讨论把东西集中在一起互相学习。希望各位都share些自己的经验。

论坛徽章:
0
9 [报告]
发表于 2007-10-29 15:32 |只看该作者
占位
做个。。。。。。

论坛徽章:
0
10 [报告]
发表于 2007-10-30 09:19 |只看该作者
本文档1.0版正式完成,现在开始征集各位的意见。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP