擴展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)
相關文章
相關標籤/搜索