Total Pageviews

Wednesday, 4 September 2013

关于apache的MPM模块详解

在一台只有512内存的vps上安装directadmin之后经常内存耗尽。经过查看之后发现apache成了罪魁祸首急速消耗内存SWAP剩余空间都是0。最终导致内核开始大下杀手,把MySQL都杀了。通过下文调整了apache的MPM参数得到解决。
apachectl -l
可以查看使用了什么MPM模块

我的VPS自从上个月配置完后一直没有再优化配置了,由于之前担心VPS的内存不够用,所以在配置服务器参数时,更多考虑如何节省内存,结果内存是省下来了,运行效率却一直不高;基于此,决定开始研究服务器参数优化。
开篇:apache prefork 模块指令

什么是MPM?
既然是研究prefork模块,有必要提一提apache的多路处理模块(MPM)的基础知识。Apache2.0拥有多个模式的多路处理模块 (MPM)以处理网络端口绑定、接受请求并指派子进程来处理这些请求。MPM延续apache的设计思想,以一个模块的形式存在与apache中,所不同 的是:任何时候,必须有且仅有一个MPM被载入到服务器中
有哪些MPM模块可供选择?
MPM有多个,我们最常用的有:prefork、worker、mpm_winnt。前面两个用于类unix系统,后者则是专门为windows系统设计的,其他的如BeOS、event、mpm_netware、mpmt_os2恕笔者所知有限,不再详述。
如何编译MPM?
为了指定具体使用哪一个MPM模块,我们必须在编译的时候设定选项 –with-mpm=Name,name为prefork之类的模块名;可以在编译完成后使用 httpd -l 查看具体那个MPM模块已安装。
prefork简介
Apache MPM prefork 实现了一个非线程型的、预派生的web服务器,它的工作方式类似于Apache 1.3。它适合于没有线程安全库,需要避免线程兼容性问题的系统。(不要看到这里就认为prefork已经过时了^_^)prefork优点在于它会独立 处理每个请求的进程,这样如果其中一个请求出现问题就不会影响到其他请求。同时可以应用于不具备线程安全的第三方模块(比如php3/4/5),且在不支 持线程调试的平台上易于调试,而且还具有比worker MPM更高的稳定性。
prefork的工作方式
prefork MPM使用多个子进程,但每个子进程并不包含多线程。并且每个进程在某一时刻也只处理一个请求。但在许多系统上它的速度和workerMPM一样快,只是内存的消耗要大一些。
prefork拥有一个单独的控制进程(父进程)负责产生子进程,这些子进程用于监听请求并作出应答。Apache随后会建立一些备用的(spare)或者是空闲的子进程用于迎接即将到来的请求。这样客户端就不需要在得到服务前等候子进程的产生(apache)。
prefork的可用指令有哪些?
StartServers, MinSpareServers, MaxSpareServers, MaxClients指令用于调节父进程如何产生子进程。MaxRequestsPerChild指令控制服务器杀死旧进程产生新进程的频率。 ServerLimit 指令则用来控制服务器允许配置的进程数上限。
上面列出的都是常用的指令,也是最重要的指令。笔者会在后面意义介绍,并给出配置实例。其他可使用的指令:
  1. AcceptMutex 用于串行化多个子进程在(多个)网络套接字(socket)上接受请求的方法
  2. CoreDumpDirectory Apache使用的内核转储目录
  3. EnableExceptionHook 在子进程崩溃以后启用一个钩子来运行异常处理程序
  4. GracefulShutdownTimeout 指定优雅停止服务器的超时秒数
  5. Group 对请求提供服务的Apache子进程运行时的用户组
  6. Listen 服务器监听的IP地址和端口
  7. ListenBackLog 半链接(pending connection)队列的最大长度
  8. LockFile 接受串行锁文件的位置
  9. MaxMemFree 主内存分配程序在未调用free()的情况下允许持有的最大自由内存数量(KB)
  10. PidFile 服务器用于记录父进程(监控进程)PID的文件
  11. ReceiveBufferSize  TCP接收缓冲区大小(字节)
  12. ScoreBoardFile 存储子进程协调数据(coordination data)的文件
  13. SendBufferSize TCP发送缓冲区大小(字节)
  14. User 实际服务于请求的子进程运行时的用户
StartServers
指定服务器启动时建立的子进程数量,prefork默认为5。
MinSpareServers
指定空闲子进程的最小数量,默认为5。如果当前空闲子进程数少于MinSpareServers ,那么Apache将以最大每秒一个的速度产生新的子进程。此参数不要设的太大。
MaxSpareServers
设置空闲子进程的最大数量,默认为10。如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程将杀死多余的子进程。此参数不要设的 太大。如果你将该指令的值设置为比MinSpareServers小,Apache将会自动将其修改成”MinSpareServers+1″。
MaxClients
对于非线程型的MPM(也就是prefork),MaxClients表示可以用于伺服客户端请求的最大子进程数量,默认值是256。任何超过 MaxClients限制的请求都将进入等候队列,一旦一个链接被释放,队列中的请求将得到服务。要增大这个值,你必须同时增大ServerLimit。
MaxRequestsPerChild
每个子进程在其生存期内允许伺服的最大请求数量,默认为10000.到达MaxRequestsPerChild的限制后,子进程将会结束。如果 MaxRequestsPerChild为”0″,子进程将永远不会结束。将MaxRequestsPerChild设置成非零值有两个好处:
1.可以防止(偶然的)内存泄漏无限进行,从而耗尽内存。
2.给进程一个有限寿命,从而有助于当服务器负载减轻的时候减少活动进程的数量。
ServerLimit
对于preforkMPM,这个指令设置了MaxClients最大允许配置的数值。对于workerMPM,这个指令和ThreadLimit结合使用 设置了MaxClients最大允许配置的数值。任何在重启期间对这个指令的改变都将被忽略,但对MaxClients的修改却会生效。
使用这个指令时要特别当心。如果将ServerLimit设置成一个高出实际需要许多的值,将会有过多的共享内存被分配。如果将ServerLimit和MaxClients设置成超过系统的处理能力,Apache可能无法启动,或者系统将变得不稳定。
对于preforkMPM,只有在你需要将MaxClients设置成高于默认值256的时候才需要使用这个指令。要将此指令的值保持和MaxClients一样。
小内存VPS配置
<IfModule prefork.c>
StartServers       3 #httpd启动时开启三个子进程
MinSpareServers    3 #最小空闲子进程
MaxSpareServers    6 #最大空闲子进程
ServerLimit      12 #prefork模式下与MaxClients 配合使用
MaxClients        12 #限制该值的目的是为了防止小内存下产生过多子进程导致服务器崩溃。
MaxRequestsPerChild  1000 #一旦子进程处理了1000个请求后自动结束旧进程,开启新进程
</IfModule>

DA-Apache MPM  /usr/local/directadmin/custombuild/configure/ap2/conf/extra/httpd-mpm.conf
<IfModule mpm_prefork_module>