1、Prefork MPM
关键字:多进程
prefork模式可以算是很古老但是非常稳定的模式。Apache在启动之初,就预派生 fork一些子进程,然后等待请求进来,并且总是视图保持一些备用的子进程。之所以这样做,是为了减少频繁创建和销毁进程的开销。每个子进程中只有一个线程,在一个时间点内,只能处理一个请求
优点:成熟,兼容所有新老模块。进程之间完全独立,使得它非常稳定。同时,不需要担心线程安全的问题。(我们常用的mod_php,PHP的拓展不需要支持线程安全)
缺点:一个进程相对占用更多的系统资源,消耗更多的内存。而且,它并不擅长处理高并发请求,在这种场景下,它会将请求放进队列中,一直等到有可用进程,请求才会被处理
httpd-mpm.conf 中的相关配置:
<IfModule mpm_prefork_module>
#服务器启动时建立的子进程数量
StartServers 5
#空闲子进程的最小数量,默认5;如果当前空闲子进程数少于MinSpareServers ,那么Apache将会产生新的子进程。此参数不要设的太大。
MinSpareServers 5
#空闲子进程的最大数量,默认10;如果当前有超过MaxSpareServers数量的空闲子进程,那么父进程会杀死多余的子进程。此参数也不需要设置太大,如果你将其设置比 MinSpareServers 小,Apache会自动将其修改为MinSpareServers+1。
MaxSpareServers 10
#限定服务器同一时间内客户端最大接入的请求数量,默认是150;任何超过了该限制的请求都要进入等待队列,一旦一个个连接被释放,队列中的请求才将得到服务。
MaxClients 150
#每个子进程在其生命周期内允许最大的请求数量,如果请求总数已经达到这个数值,子进程将会结束,如果设置为0,子进程将永远不会结束。若该值设置为非0值,可以防止运行PHP导致的内存泄露。
MaxRequestsPerChild 0
</IfModule>
2、Worker MPM
关键字:多进程+多线程
worker模式比起上一个,是使用了多进程+多线程的模式。它也预先fork了几个子进程(数量比较少),每个子进程能够生成一些服务线程和一个监听线程,该监听线程监听接入请求并将其传递给服务线程处理和应答
优点:占据更少的内存,高并发下表现更优秀。
缺点:必须考虑线程安全的问题,因为多个子线程是共享父进程的内存地址的。如果使用keep-alive的长连接方式,也许中间几乎没有请求,这时就会发生阻塞,线程被挂起,需要一直等待到超时才会被释放。如果过多的线程,被这样占据,也会导致在高并发场景下的无服务线程可用。(该问题在prefork模式下,同样会发生)
Ps:http1.1的keep-alive的长连接方式,是为了让下一次的socket通信复用之前创建的连接,从而,减少连接的创建和销毁的系统开销。保持连接,会让某个进程或者线程一直处于等待状态,即使没有数据过来
<IfModule mpm_worker_module>
#服务器启动时建立的子进程数量
StartServers 2
#限定服务器同一时间内客户端最大接入的请求数量,默认是150;任何超过了该限制的请求都要进入等待队列,一旦一个个连接被释放,队列中的请求才将得到服务。
MaxClients 150
#空闲子进程的最小数量
MinSpareThreads 25
#空闲子进程的最大数量
MaxSpareThreads 75
#每个子进程产生的线程数量
ThreadsPerChild 25
#每个子进程在其生命周期内允许最大的请求数量,如果请求总数已经达到这个数值,子进程将会结束,如果设置为0,子进程将永远不会结束。将该值设置为非0值,可以防止运行PHP导致的内存泄露。
MaxRequestsPerChild 0
</IfModule>
3、Event MPM
关键字:多进程+多线程+epoll
这个是 Apache中最新的模式,在现在版本里的已经是稳定可用的模式。它和 worker模式很像,最大的区别在于,它解决了 keep-alive 场景下 ,长期被占用的线程的资源浪费问题(某些线程因为被keep-alive,挂在那里等待,中间几乎没有请求过来,一直等到超时)。
event MPM中,会有一个专门的线程来管理这些 keep-alive 类型的线程,当有真实请求过来的时候,将请求传递给服务线程,执行完毕后,又允许它释放。这样,一个线程就能处理几个请求了,实现了异步非阻塞
注意一点,event MPM需要Linux系统(Linux 2.6+)对Epoll的支持,才能启用
<IfModule mpm_worker_module>
#服务器启动时建立的子进程数量
StartServers 3
#空闲子进程的最小数量
MinSpareThreads 75
#空闲子进程的最小数量
MaxSpareThreads 250
#每个子进程产生的线程数量
ThreadsPerChild 25
#限定服务器同一时间内客户端最大接入的请求数量,默认是150;任何超过了该限制的请求都要进入等待队列,一旦一个个连接被释放,队列中的请求才将得到服务。
MaxRequestWorkers 400
#每个子进程在其生命周期内允许最大的请求数量,如果请求总数已经达到这个数值,子进程将会结束,如果设置为0,子进程将永远不会结束。将该值设置为非0值,可以防止运行PHP导致的内存泄露。
MaxRequestsPerChild 0
</IfModule>
工作模块启动脚本:
脚本中解压的压缩包可以网上自行下载或到https://download.csdn.net/download/yplayer001/11899508下载
#!/bin/bash
#Apache的压缩和缓存
#-------------------Apache压缩和缓存--------------------
#将文件放在root家目录中直接解压,解压到/opt文件中
tar zvxf apr-1.6.2.tar.gz -C /opt
tar zvxf apr-util-1.6.0.tar.gz -C /opt
tar jvxf httpd-2.4.29.tar.bz2 -C /opt
mv /opt/apr-1.6.2 /opt/httpd-2.4.29/srclib/apr
mv /opt/apr-util-1.6.0 /opt/httpd-2.4.29/srclib/apr-util
#安装软件包
yum -y install \
gcc \
gcc-c++ \
pcre \
pcre-devel \
zlib-devel \
expat-devel
cd /opt/httpd-2.4.29
./configure \
--prefix=/usr/local/httpd \
--enable-expires \
--enable-deflate \
--with-mpm=worker \
--enable-so \
--enable-rewrite \
--enable-charset-lite \
--enable-cgi
#编译和安装
make && make install
#配置监听端口
sed -i '51s/#Listen 12.34.56.78:80/Listen 192.168.154.152:80/' /usr/local/httpd/conf/httpd.conf
sed -i '52s/^/#/' /usr/local/httpd/conf/httpd.conf
#配置服务名称
sed -i '198s/#//' /usr/local/httpd/conf/httpd.conf
sed -i 's/example/kgc/' /usr/local/httpd/conf/httpd.conf
sed -i '463s/#//' /usr/local/httpd/conf/httpd.conf ##开启apache工作模块
cd /usr/local/httpd/bin
./apachectl start
#---------------------三个工作模块(可优化)----------------------
#vim /usr/local/httpd/conf/extra/httpd-mpm.conf
#Apache中profork模块优化建议
#<IfModule mpm_prefork_module>
# StartServers 10
# MinSpareServers 10
# MaxSpareServers 30
# MaxRequestWorkers 256
# MaxConnectionsPerChild 5000
#</IfModule>
#Apache中worker模块优化建议
#<IfModule mpm_worker_module>
# StartServers 10
# MinSpareThreads 10
# MaxSpareThreads 30
# ThreadsPerChild 25
# MaxRequestWorkers 400
# MaxConnectionsPerChild 0
#</IfModule>
#Apache中event模块优化建议
#<IfModule mpm_event_module>
# StartServers 20
# MinSpareThreads 25
# MaxSpareThreads 1200
# ThreadsPerChild 50
# MaxRequestWorkers 2000
# MaxConnectionsPerChild 1000
#</IfModule>
#具体优化数据上网自行百度