扩展40.1:Apache的三种工做模式(perfork、worker、event)

注释:2.2版本的默认工做模式是worker,           2.4版本的默认工做模式是event;php

一、Apache的工做模式MPM=(perfork wroker  event winnt),经常使用的有 perfork   worker  event三种linux

二、调整某种模式的所在配置文件:/usr/local/apache2.4/conf/extra/httpd-mpm.confweb

注释:在2.3.13以前,MaxRequestWorkers  被称为是Maxclient;apache

1: 查看apache有的几种工做模式:在httpd的目录下运行./configure --helpvim

[root@localhost_02 httpd-2.4.34]# ./configure --help
--with-mpm=MPM      Choose the process model for Apache to use by
                    default. MPM={event|worker|prefork|winnt} This will
                     be statically linked as the only available MPM
                     unless --enable-mpms-shared is also specified.

2:查看当前apache处于那种工做模式:    /usr/local/apapche2.4/bin/apache    -l安全

[root@localhost_02 httpd-2.4.34]# /usr/local/apapche2.4/bin/apachectl -l
Compiled in modules:
  core.c
  mod_so.c
  http_core.c
  event.c

注释:当前处于event.c工做模式:  /usr/local/apapche2.4/bin/apache -lbash

注释:查看apached的编译参数:/usr/local/apapche2.4/build/config.nice服务器

注释:工做模式所在的配置文件:  /usr/local/apapche2.4/conf/extra/httpd-mpm.conf网络

3:修改apache工做模式有两种方式多线程

1:经过开始编译apache时,经过./configure --with-mpm=perfork|worker|event|来指定:

./configure --prefix=/usr/local/apache2.4  --with-apr=/usr/local/apr  --with-apr-util=/usr/local/apr-util  --with-mpm=perork|worker|event     --enable-so  --enable-mods-shared=most 

[root@localhost_04 httpd-2.4.37]# ./configure --prefix=/usr/local/apache2.4 --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-mpm=prefix --enable-so --enable-mods=most

2:经过开始编译时把三个模块都编译进去,都编译成动态文件,而后就能够在modules目录下看到perfork.so   worker.so   event.so三个文件,默认用的event(2.4版本);

[root@localhost_04 httpd-2.4.37]# ./configure --prefix=/usr/local/apache2.4 --with-apr=/usr/local/apr --with-apr-util=/usr/local/apr-util --with-included-apr --enable-so --enable-mods-shared=most --enable-mpms-shared=all --with-mpm=event
[root@localhost_04 httpd-2.4.37]# make && make install
[root@localhost_04 httpd-2.4.37]# cp /usr/local/apache2.4/bin/apachectl /etc/init.d/httpd
[root@localhost_04 httpd-2.4.37]# vim /etc/init.d/httpd
#!/bin/sh
#chkconfig:345 85 15
#description:Start and stop the Apache HTTP Server
[root@localhost_04 httpd-2.4.37]# chkconfig --add httpd

3:查看其编译参数及工做模式;

[root@localhost_04 httpd-2.4.37]# cat /usr/local/apache2.4/build/config.nice

工做模式:发现变成了动态的:mpm_event-module(shared)

[root@localhost_04 httpd-2.4.37]# /usr/local/apache2.4/bin/httpd -M
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 192.168.149.132. Set the 'ServerName' directive globally to suppress this message
Loaded Modules:
 core_module (static)
 so_module (static)
 http_module (static)
 mpm_event_module (shared)

4:而后来查看下apache的配置文件httpd.conf,经过其来修改工做模式;

[root@localhost_04 httpd-2.4.37]# cat /usr/local/apache2.4/conf/httpd.conf |grep -B3 mpm
# Example:
# LoadModule foo_module modules/mod_foo.so
LoadModule mpm_event_module modules/mod_mpm_event.so
#LoadModule mpm_prefork_module modules/mod_mpm_prefork.so
#LoadModule mpm_worker_module modules/mod_mpm_worker.so

注释:经过如上图例发现目前使用的模式mpm_event_modules模式,如需更改,则去掉对应的"#"号,而后重启服务便可;以下;

[root@localhost_04 httpd-2.4.37]# service httpd restart
[root@localhost_04 httpd-2.4.37]# /usr/local/apache2.4/bin/httpd -M
Loaded Modules:
 core_module (static)
 so_module (static)
 http_module (static)
 mpm_prefork_module (shared)

注释:如上图例,此时则变成了mpm_perfork_module(shared)模式;

那三种模式有什么区别了呢;  perork    worker    event

1:  perfork  mpm       多进程

这是一种很古老可是很是稳定的模式原理,非线程的,apache在刚启动的时候,就会profork的一些子进程(属主是daemon)也会保持一些备用的进程,而后等待请求进来,而且呢,每一个子进程只有一个线程,也就是说只能处理一个请求,一直到这个请求被释放了;

注释:在linux系统中,httpd的父进程以root用户身份运行并绑定80端口,而apache的子进程是以一个很低权限的用户(daemon)在运行,只让它读要服务的内容有读取权限,对服务器之外的资源尽量少的权限;

[root@localhost_04 httpd-2.4.37]# ps aux |grep httpd
root      54617  0.0  0.2  97388  2380 ?        Ss   11:21   0:00 /usr/local/apache2.4/bin/httpd -k restart
daemon    54634  0.0  0.1  97388  1624 ?        S    11:21   0:00 /usr/local/apache2.4/bin/httpd -k restart
daemon    54635  0.0  0.1  97388  1624 ?        S    11:21   0:00 /usr/local/apache2.4/bin/httpd -k restart
daemon    54636  0.0  0.1  97388  1624 ?        S    11:21   0:00 /usr/local/apache2.4/bin/httpd -k restart
daemon    54637  0.0  0.1  97388  1624 ?        S    11:21   0:00 /usr/local/apache2.4/bin/httpd -k restart
daemon    54638  0.0  0.1  97388  1624 ?        S    11:21   0:00 /usr/local/apache2.4/bin/httpd -k restart
root      54640  0.0  0.0 112720   968 pts/0    R+   11:21   0:00 grep --color=auto httpd
[root@localhost_04 httpd-2.4.37]# id daemon
uid=2(daemon) gid=2(daemon) 组=2(daemon)

2:修改perfork的参数(配置文件目录/usr/local/apache2.4/conf/extra/httpd-mpm.conf)

[root@localhost_04 extra]# vim 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
# MaxRequestWorkers: maximum number of server processes allowed to start
# MaxConnectionsPerChild: maximum number of connections a server process serves
<IfModule mpm_prefork_module>
    StartServers             5             #服务启动时子进程的数量;默认是5个;
    MinSpareServers          5             #空闲时子进程的最小数量; 默认是5个;不够则自动建立新的子进程;
    MaxSpareServers         10             #空闲时子进程的最大数量; 默认是10个;多了则杀死多的字进程;
    MaxRequestWorkers      250  #默认150,同一时间内客户端接入最大的请求数量,超事后这等待进程释放后再接入;
    MaxConnectionsPerChild   0  #每一个子进程处理多少个链接后,自动销毁,0表示一直不结束;    
</IfModule>

StartServers             5                  #服务启动时子进程的数量;默认是5个;
MinSpareServers          5             #空闲时子进程的最小数量; 默认是5个;不够则自动建立新的子进程;
MaxSpareServers         10            #空闲时子进程的最大数量; 默认是10个;多了则杀死多的字进程;
MaxRequestWorkers      250       #默认150,同一时间内客户端接入最大的请求数量,超事后这等待进程释放后再接入;            MaxConnectionsPerChild   0       #每一个子进程生命周期内最大请求数量,若是到达这个数量,子进程会结束;0表示一直不结束;

注释:在2.3.13以前,MaxRequestWorkers  被称为是Maxclient;

注释:若是须要加大MaxRequestWorkers这个参数,则须要同时增长serverlimit;  通常设置为20000;

注释:当网站负载量过大时,能够适当加大MinSpareServers和MaxSpareServers这两个参数;

perfork模式的优点:比较成熟稳定,兼容全部新老模块,而且进程之间相互独立,同时须要担忧线程的安全问题(php_mod不支持线程安全)

perfork莫得的缺点:每个进程占用的系统资源比较多(cpu 内存等),不擅长于处理高并发,当请求量大的时候,它会将后面的请求放进队列,一直要等到有可用的进程,才会去处理;

2:worker模式:   多线程+多进程

worker模式使用多进程多线程的模式,服务启动时预先生出一些子进程(数量少),而后每一个子进程生出一些服务线程一个监听线程;监听线程负责监听web请求并将其传递给服务线程去处理;

注释:apache服务会维持一个空闲的服务线程池,这样能够保证客户端的请求过来时无需等待,等到及时的处理和响应;

那怎么是线程,什么是进程呢;

线程是进程的子单元,同一个父进程下的线程共享父进程的内存,线程比进程更轻量;

全部在高并发场景下的worker使用要优于perfork;

注释:那么为何不直接使用多线程了,那岂不是很方便省事,为何要引入多进程的概念;

保证稳定性和安全性,若是直接使用多线程来启动,那全部的线程都都在root这个父进程下,那么一旦其中一个线程挂了,会致使其它线程父进程都挂了;

而在多进程+多线程模式下,每一个进程之间是相互隔离,若是某个线程出现异常,影响的也只是一个父进程和其子进程,而不是整个服务,其它线程能够正常工做;

配置文件: /usr/local/apache2.4/conf/extra/httpd-mpm.conf 

[root@localhost_04 extra]# vim httpd-mpm.conf 
# worker MPM
# StartServers: initial number of server processes to start
# 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
# MaxRequestWorkers: maximum number of worker threads
# MaxConnectionsPerChild: maximum number of connections a server process serves
<IfModule mpm_worker_module>
    StartServers             3        #服务启动时创建的子进程数量; 默认是3;
    MinSpareThreads         75        #空闲子线程的最小数量;  默认是75;
    MaxSpareThreads        250        #空闲子线程的最大数量;  默认是250;
    ThreadsPerChild         25        
    MaxRequestWorkers      400       #每一个子线程处理的最大链接数;超事后则再队列内等待;
    MaxConnectionsPerChild   0       #每一个子线程生命周期内处理的请求数量,到达这个数量,子线程会结束,0表示不结束;
</IfModule>

注释:在2.3.13以前,MaxRequestWorkers  被称为是Maxclient;

    StartServers             3                       #服务启动时创建的子进程数量; 默认是3;
    MinSpareThreads         75               #空闲子线程的最小数量;  默认是75;
    MaxSpareThreads        250             #空闲子线程的最大数量;  默认是250;
    ThreadsPerChild          25                #每一个子线程的最大链接数;
    MaxRequestWorkers      400            #每一个子线程处理的最大链接数;超事后则再队列内等待;
    MaxConnectionsPerChild   0           #每一个子线程生命周期内处理的请求数量,到达这个数量,子线程会结束,0表示不结束;

[root@localhost_04 conf]# ps aux |grep httpd
root      54703  0.0  0.1  97304  1904 ?        Ss   12:41   0:00 /usr/local/apache2.4/bin/httpd -k start
root      54705  0.0  0.0 112720   972 pts/0    R+   12:41   0:00 grep --color=auto httpd 
[root@localhost_04 conf]# /usr/local/apache2.4/bin/apachectl -M
Loaded Modules:
 core_module (static)
 so_module (static)
 http_module (static)
 mpm_worker_module (shared)


worker模式的优点:占据更少的内存,高并发小表现的更加优秀;

worker模式的缺点:必需要考虑线程的安全问题,由于多个线程 是共享父进程的内存的,若是是keep-alive的长链接,中间没有请求,这个线程就会被挂起,会发生阻塞;须要一直等到超时后才被释放,若是过多的线程被这样占据,会致使高并发场景下无服务线程可用;(该问题在perfork模式下,也一样存在)

注释:http的keep-alive长链接方式,是为了让下一次通讯的时候还能够用以前的链接,这样能够减小建立链接产生的开销,而若是保持链接了会让某个进程或线程一直处理等待状态,即便没有请求过来;

注释:因为perfork和worker在高并发下有些不足,尽管keep-alive能较少TCP链接的网络开销,可是须要和进程或者线程相互绑定到一块儿,即便没有请求也会等待直到超时;

3、event    多进程+多线程+epoll

这是apache的最新的工做模式,基本是很稳定了,它和worker模式很像,最大的差异在于它解决了keep-alive长链接问题(被keep-alive的线程即便没有请求,也会被挂在哪里一直到超时才结束);

在event模式中,会有一个专门的线程来管理这些keep-alive的线程,当请求过来时,将请求转发给服务线程,处理完成后,又容许它释放,这样,一个线程就能够处理多个请求了,实现了异步非阻塞

注释:event工做模式遇到某些不兼容的模块,会自动回退到worker模式(一个线程处理一个请求),不过官方自带模块,都是支持event工做模式的;

注释:event工做模式下,服务器处理的速度很是快,能承受每秒好几万次的访问量,能够处理高负载;

event工做模式不能再安全http(https)的访问下工做

配置文件: /usr/local/apache2.4/conf/extra/httpd-mpm.conf 

[root@localhost_04 extra]# vim httpd-mpm.conf 
# event MPM
# StartServers: initial number of server processes to start
# 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
# MaxRequestWorkers: maximum number of worker threads
# MaxConnectionsPerChild: maximum number of connections a server process serves
<IfModule mpm_event_module>
    StartServers             3    #服务后创建的子进程数量;默认3个:
    MinSpareThreads         75    #空闲时最少子线程数量;默认75个;
    MaxSpareThreads        250    #空闲时最打字进程数量;默认250个;
    ThreadsPerChild         25    #每一个子线程的最大链接数;
    MaxRequestWorkers      400    #子线程的处理请求,超事后则再队列等待;
    MaxConnectionsPerChild   0    #每一个子线程处理最多链接请求,超过这个值后,子线程结束,0表示不结束;
</IfModule>

StartServers             3    #服务后创建的子进程数量;默认3个:
MinSpareThreads         75    #空闲时最少子线程数量;默认75个;
MaxSpareThreads        250    #空闲时最打字进程数量;默认250个;
ThreadsPerChild         25    #每一个子线程的最大链接数;
MaxRequestWorkers      400    #子线程的处理请求,超事后则再队列等待;
MaxConnectionsPerChild   0    #每一个子线程处理最多链接请求,超过这个值后,子线程结束,0表示不结束;

[root@localhost_04 conf]# ps aux |grep httpd
root      54818  0.0  0.1  97320  1912 ?        Ss   12:58   0:00 /usr/local/apache2.4/bin/httpd -k start
root      54820  0.0  0.0 112720   968 pts/0    S+   12:58   0:00 grep --color=auto httpd
[root@localhost_04 conf]# /usr/local/apache2.4/bin/apachectl -M
Loaded Modules:
 core_module (static)
 so_module (static)
 http_module (static)
 mpm_event_module (shared)

流程图以下;

那么如何查询当前是那种工做模式:以下两种方法;

若是是静态编译工做模式的一种;以下命令;会显示 perfork.c | worker.c |event.c

[root@localhost_04 conf]# /usr/local/apache2.4/bin/apachectl -l
Compiled in modules:
  core.c
  mod_so.c
  http_core.c

若是是动态编译三种工做模式;以下命令;

[root@localhost_04 conf]# /usr/local/apache2.4/bin/apachectl -M
Loaded Modules:
 core_module (static)
 so_module (static)
 http_module (static)
 mpm_event_module (shared)
 authn_file_module (shared)
 authn_core_module (shared)
相关文章
相关标签/搜索