註釋: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)