一、简介
httpd-2.x版本引入了插入式的并行处理模式,多路处理模块(MPM),其有三种运行模式,分别是prefork、worker和event,对于event模式在httpd-2.2来说还在于测试阶段,通常来说不会在生成环境上面运行,而在httpd-2.4上event模式已经完成测试,可以在生产环境上运行了。
1、prefork
prefork是一个两级进程模型,非线程的模式,其实通过由父进程管理创建子进程,子进程相应的相应的请求的方式来运行的。以prefork模式运行的httpd,在启动之际就预派生fork了一些子进程,然后等待请求。每个子进程只有一个线程,在一个时间点内只能处理一个请求。
优点:成熟、稳定、兼容所有新老模块。进程之间完全独立,无须担心线程安全的问题。
缺点:一个进程相对会占用更多的系统资源,消耗更多的内存。不适合处理高并发请求,因其会把请求放进队列中,一直等到有可用进程才会处理相应的请求。
在httpd-2.2中的配置:
<IfModule prefork.c>
StartServers 8 #进程启动时创建多个子进程
MinSpareServers 5 #最少空闲进程数
MaxSpareServers 20 #最大空闲进程数
ServerLimit 256 #服务器支持的最大进程数
MaxClients 256 #允许的最大并发请求数量,对于prefork即为最大并发的子进程数量
MaxRequestsPerChild 4000 #设置的是每个子进程可处理的请求数。每个子进程在处理了指定个请求后将自动销毁。0意味着无限,即子进程永不销毁。
</IfModule>
2、worker
worker是一个三级结构、多进程多线程的模式,其在启动时也预先fork了几个子进程,每个子进程能够生产若干个服务线程和若干个监听线程,每个服务线程处理一个请求,监听线程负责接入请求并将其传递给服务线程处理和应答。线程比起进程会更轻量,因为线程通常会共享父进程的内存空间,因此内存的占用会减少些,在高并发的场景下表现比prefork模式好。
优点:占用内存少,高并发性能更优秀。
缺点:当一个线程出现问题的时候会导致同一进程下的线程也会出现问题。在keep-alive长连接的方式下,某个线程会被一直占用,即使中间没有请求,也需要等待到超时才会被释放。
在httpd-2.2中的配置:
<IfModule worker.c>
StartServers 4 #服务器启动时建立的子进程数量
MaxClients 300 #限制同一时间并发请求的数量
MinSpareThreads 25 #设置空闲线程的最小数量
MaxSpareThreads 75 #设置空闲线程的最大数量
ThreadsPerChild 25 #设置每个子进程产生的最大线程数量
MaxRequestsPerChild 0 #设置的是每个子进程可处理的请求数。每个子进程在处理了指定个请求后将自动销毁。0意味着无限,即子进程永不销毁。
</IfModule>
3、event
event模式是最新的运行模式,在httpd-2.4中已经是稳定可用的模式。其运行原理与worker类似,区别在于,event模式解决了在keep-alive模式下,线程被长期占用直到超时,从而导致资源浪费的问题。
在event模块中,有一个专门的线程来管理这些keep-alive类型的线程,当接收到真实的请求时,会将请求传递给服务线程,执行完毕后,会将对应的服务线程释放,这样就能实现线程的异步非阻塞。
在httpd-2.2中的配置:
<IfModule mpm_event_module>
StartServers 3 #服务启动时建立的子进程的数量
MinSpareThreads 75 #空闲线程的最少数量
MaxSpareThreads 250 #空闲线程的最大数量
ThreadsPerChild 25 #每个子进程产生的线程数量
Maxclients 400 #最大的并发的线程数
MaxRequestsPerChild 0 #每个子进程处理的最大连接数,0表示不限制。
</IfModule>
二、在Centos 6 上安装httpd 2.2,并实现prefork、worker、event模式的运行
在Centos 6.9上安装httpd 2.2:
[root@localhost ~]# yum install httpd -y
- prefork
安装完成后,httpd的默认运行模式为prefork,查看其运行模式为:
[root@localhost ~]# httpd -M | grep mpm
httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName
mpm_prefork_module (static)
Syntax OK
在/etc/httpd.conf中查看其对应prefork配置:
# 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
# ServerLimit: maximum value for MaxClients for the lifetime of the server
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule prefork.c>
StartServers 8
MinSpareServers 5
MaxSpareServers 20
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
</IfModule>
启动httpd服务并查看相关的进程状态:
[root@localhost ~]# ps aux | grep httpd
root 33315 0.0 0.5 139104 5356 pts/2 S+ 10:29 0:00 vim /etc/httpd/conf/httpd.conf
root 33362 0.0 0.3 175396 3784 ? Ss 10:31 0:00 /usr/sbin/httpd
apache 33364 0.0 0.2 175396 2480 ? S 10:31 0:00 /usr/sbin/httpd
apache 33365 0.0 0.2 175396 2464 ? S 10:31 0:00 /usr/sbin/httpd
apache 33366 0.0 0.2 175396 2464 ? S 10:31 0:00 /usr/sbin/httpd
apache 33367 0.0 0.2 175396 2464 ? S 10:31 0:00 /usr/sbin/httpd
apache 33368 0.0 0.2 175396 2464 ? S 10:31 0:00 /usr/sbin/httpd
apache 33369 0.0 0.2 175396 2464 ? S 10:31 0:00 /usr/sbin/httpd
apache 33370 0.0 0.2 175396 2464 ? S 10:31 0:00 /usr/sbin/httpd
apache 33371 0.0 0.2 175396 2464 ? S 10:31 0:00 /usr/sbin/httpd
root 33389 0.0 0.0 103328 880 pts/3 S+ 10:32 0:00 grep httpd
#初始启动后创建了8个以apache用户身份运行的httpd子进程,符合配置文件中的StartServers值
修改 /etc/httpd/conf/httpd.conf中的prefork配置:
<IfModule prefork.c>
StartServers 5 #修改启动时创建的进程数为5
MinSpareServers 5
MaxSpareServers 15 #设置空闲进程为15
ServerLimit 20
MaxClients 20 #修改最大并发请求的数量为20
MaxRequestsPerChild 4000
</IfModule>
重启httpd服务并查看相应的进程:
[root@localhost ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName
[ OK ]
[root@localhost ~]# ps aux | grep httpd
root 33452 0.0 0.3 175396 3784 ? Ss 10:39 0:00 /usr/sbin/httpd
apache 33454 0.0 0.2 175396 2484 ? S 10:39 0:00 /usr/sbin/httpd
apache 33455 0.0 0.2 175396 2468 ? S 10:39 0:00 /usr/sbin/httpd
apache 33456 0.0 0.2 175396 2468 ? S 10:39 0:00 /usr/sbin/httpd
apache 33457 0.0 0.2 175396 2468 ? S 10:39 0:00 /usr/sbin/httpd
apache 33458 0.0 0.2 175396 2468 ? S 10:39 0:00 /usr/sbin/httpd
root 33460 0.0 0.0 103328 880 pts/3 S+ 10:39 0:00 grep httpd
#符合相应预期的设置
使用ab工具对相应的URL进行压力测试并观察进程的状况:
[root@localhost ~]# ab -n 100000 -c 30 http://188.88.88.171/index.html


- worker
对于httpd-2.2版本来说,要更改运行模式为worker模式,需先修改配置文件/etc/sysconfig/httpd:
[root@localhost ~]# vim /etc/sysconfig/httpd
HTTPD=/usr/sbin/httpd.worker #找到相应的内容取消注释
重启httpd服务后,查看进程状态:
[root@localhost ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: httpd.worker: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName
[ OK ]
[root@localhost ~]# ps -ef | grep httpd
root 36842 33332 0 11:12 pts/3 00:00:06 watch ps -ef | grep ^apache.*/usr/sbin/httpd | wc -l
root 67282 1 0 15:08 ? 00:00:00 /usr/sbin/httpd.worker #程序的名称说明已成功切换为worker模式
apache 67284 67282 0 15:08 ? 00:00:00 /usr/sbin/httpd.worker
apache 67285 67282 0 15:08 ? 00:00:00 /usr/sbin/httpd.worker
root 67359 34809 0 15:08 pts/4 00:00:00 grep httpd
修改 /etc/httpd/conf/httpd.conf文件中的worker的配置:
<IfModule worker.c>
StartServers 2
MaxClients 200 #更改最大并发请求的数量为200,按照一个子进程负责处理25个线程的比例,此处即最大支持并发8个子进程
MinSpareThreads 25
MaxSpareThreads 200 #修改最大空闲线程的数量为200,按照一个子进程负责处理25个线程的比例,此处即最大空闲支持4个子进程
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
重启httpd服务后,使用ab工具进行压力测试:
[root@localhost ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: httpd.worker: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName
[ OK ]
压测命令:ab -n 200000 -c 300 http://188.88.88.171/index.html


- event
http-2.2的event模式还处于测试阶段,因此不建议在生产环境上运行,httpd-2.4的event模式为正式版可在生产环境上部署。
修改配置文件/etc/sysconfig/httpd:
[root@localhost ~]# vim /etc/sysconfig/httpd
HTTPD=/usr/sbin/httpd.event #修改为/usr/sbin/httpd.event
重启httpd服务,并查看httpd服务:
[root@localhost ~]# service httpd restart
Stopping httpd: [ OK ]
Starting httpd: httpd.event: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName
[ OK ]
[root@localhost ~]# ps -ef | grep httpd
root 36842 33332 0 11:12 pts/3 00:00:07 watch ps -ef | grep ^apache.*/usr/sbin/httpd | wc -l
root 85909 1 0 16:24 ? 00:00:00 /usr/sbin/httpd.event
apache 85911 85909 0 16:24 ? 00:00:00 /usr/sbin/httpd.event
apache 85912 85909 0 16:24 ? 00:00:00 /usr/sbin/httpd.event
apache 85913 85909 0 16:24 ? 00:00:00 /usr/sbin/httpd.event
apache 85914 85909 0 16:24 ? 00:00:00 /usr/sbin/httpd.event
apache 85915 85909 0 16:24 ? 00:00:00 /usr/sbin/httpd.event
root 86201 34809 0 16:25 pts/4 00:00:00 grep httpd
修改/etc/httpd/conf/httpd.conf,添加event配置:
<IfModule mpm_event_module>
StartServers 5 #启动时建立5个子进程
MinSpareThreads 25 #最小空闲线程数量
MaxSpareThreads 250
ThreadsPerChild 25
MaxClients 300 #修改最大并发请求的值为400
MaxRequestsPerChild 0
</IfModule>
压测命令:ab -n 200000 -c 300 http://188.88.88.171/index.html

三、后记
在测试启动httpd 的各种模式的过程中,我曾尝试编译安装后启动worker模式,但是发现其worker进程状态跟配置文件里头的worker设置并不一致,最初以为是配置错误,但是后来经测试验证发现,通过yum安装后配置同样的设置,得出的结果是正确的,所以初步判断为编译安装的问题,相比yum安装,我做的编译安装缺少了挺多文件的,但是因为水平有限,无法完整编译出正确的安装。因此在此记录下相关的问题和现象,以便后续学习研究透了后进行回顾。


编译安装httpd-2.2的命令:
./configure --prefix=/usr/local/httpd --sysconfdir=/etc/httpd --enable-so --enable-deflate --enable-headers --enable-rewrite --with-mpm=worker --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util/ --with-program-name=/usr/sbin/httpd.worker
make && make install
网友评论