httpd的运行模式prefork、worker、event

2018-04-27  本文已影响0人  小尛酒窝

一、简介

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

安装完成后,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
prefork模式一个子进程对应一个请求,观察测试过程中,其httpd的子进程最大数量为20,跟在/etc/httpd.conf文件中的prefork设置相一致。 测试结束后,因最大空闲进程的设置,相关子进程减少到15个。

对于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

测试过程中,并发的子进程个数为8个,符合worker的设置 测试结束后,因最大空闲线程的设置,子进程数减少到6个

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

测试过程中,进程数最高为12,跟MaxClient的设置相一致

三、后记

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


worker模式中进程数与配置不一致,通过httpd -M 确认了worker模式已正常编译安装
压测第一个进程基本没用

编译安装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
上一篇 下一篇

猜你喜欢

热点阅读