摘要:全稱是多道處理模塊我們都知道是以模塊化方式設(shè)計(jì)的那么用來決定如何處理用戶請(qǐng)求的是通過一個(gè)進(jìn)程處理一個(gè)請(qǐng)求還是一個(gè)線程處理一個(gè)請(qǐng)求當(dāng)前有三種可以選擇的方式雖然有以上三種方式但是要注意在任何時(shí)間必須有一個(gè)而且只能有一個(gè)被使用那么下面就介紹一下這
preforkMPM全稱是多道處理模塊,我們都知道apache是以模塊化方式設(shè)計(jì)的.那么MPM用來決定apache如何處理用戶請(qǐng)求的.是通過一個(gè)進(jìn)程處理一個(gè)請(qǐng)求,還是一個(gè)線程處理一個(gè)請(qǐng)求.當(dāng)前MPM有三種可以選擇的方式:
prefork
worker
event
雖然有以上三種方式,但是要注意在任何時(shí)間,必須有一個(gè),而且只能有一個(gè)MPM被使用.那么下面就介紹一下這三種處理方式的區(qū)別.
在這種工作模型下,apache進(jìn)程分為master進(jìn)程跟worker進(jìn)程.web服務(wù)啟動(dòng)就是啟動(dòng)master進(jìn)程,隨之master進(jìn)程會(huì)啟動(dòng)若干個(gè)worker子進(jìn)程.master進(jìn)程的工作就是管理worker子進(jìn)程.而worker子進(jìn)程的工作就是處理用戶請(qǐng)求.當(dāng)用戶發(fā)起一個(gè)請(qǐng)求,apache就會(huì)從空閑的子進(jìn)程中選擇一個(gè)處理這個(gè)用戶請(qǐng)求.
這種處理方式有以下幾點(diǎn)好處:
用戶不用等到其他進(jìn)程處理完畢.因?yàn)橹灰锌臻e子進(jìn)程在就可以處理新的請(qǐng)求
如果一個(gè)worker子進(jìn)程崩潰了,不會(huì)影響其他worker進(jìn)程處理請(qǐng)求.
但是worker子進(jìn)程的個(gè)數(shù)限制于apache配置文件中如下幾個(gè)條目的限制
MinSpareServers 最少空閑worker進(jìn)程.
MaxSpareServers最多空閑worker進(jìn)程,超過這個(gè)數(shù),就會(huì)有一些空閑worker進(jìn)程被kill
MaxRequestWorkers同一時(shí)刻可以處理的請(qǐng)求數(shù),即并發(fā)量
MaxConnectionsPerChild每一個(gè)worker子進(jìn)程一生中可以處理的請(qǐng)求,超過這個(gè)數(shù)之后就會(huì)被master進(jìn)程kill
同時(shí), 一般master進(jìn)程使用root用戶啟動(dòng),這樣方便master進(jìn)程監(jiān)聽80端口,以及管理進(jìn)程.而余下的worker子進(jìn)程則是以apache配置文件中User指令指定的用戶啟動(dòng).這樣子是為了減少worker子進(jìn)程的權(quán)限.保證安全.
root@ff1221aa94a9:~# ps -aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 4448 676 ? Ss 09:33 0:00 /bin/sh -c supervisord -n root 5 0.0 0.8 60556 17172 ? S 09:33 0:02 /usr/bin/python /usr/bin/supervisord -n root 31 0.0 0.1 61384 3160 ? Ss 09:33 0:00 /usr/sbin/sshd root 32 0.0 0.8 200164 16384 ? Ss 09:33 0:00 /usr/local/apache/bin/httpd -k start daemon 33 0.0 0.4 200300 8392 ? S 09:33 0:00 /usr/local/apache/bin/httpd -k start daemon 34 0.0 0.3 200300 7512 ? S 09:33 0:00 /usr/local/apache/bin/httpd -k start daemon 35 0.0 0.3 200300 7512 ? S 09:33 0:00 /usr/local/apache/bin/httpd -k start daemon 36 0.0 0.3 200300 7512 ? S 09:33 0:00 /usr/local/apache/bin/httpd -k start daemon 37 0.0 0.3 200300 7512 ? S 09:33 0:00 /usr/local/apache/bin/httpd -k start
執(zhí)行ps可以看出只有一個(gè)master進(jìn)程以root用戶方式啟動(dòng)
workerprefork的缺點(diǎn)很明顯,一個(gè)worker進(jìn)程處理一個(gè)請(qǐng)求,并發(fā)不會(huì)高.而且進(jìn)程占用的資源太多.做的事情卻只是處理一個(gè)請(qǐng)求.worker針對(duì)prefork的問題進(jìn)行了改進(jìn).
仍然有一個(gè)master父進(jìn)程啟動(dòng)若干個(gè)子進(jìn)程
每個(gè)子進(jìn)程啟動(dòng)若干個(gè)線程
每個(gè)線程處理每個(gè)請(qǐng)求
這樣子,worker模型的并發(fā)性高于prefork模型.并且由于線程的開銷小于進(jìn)程,所以worker模型占用的資源反而小于prefork.
但是worker相對(duì)于prefork存在一個(gè)問題:非線程安全.最典型的一個(gè)問題在于:如果你的apache使用了worker模型工作.但是php卻使用非線程安全的版本,那么這兩者就不能工作了.所以縱然worker有萬般好,但是碰到使用非線程安全的歷史代碼,還是只能乖乖使用prefork模型.
worker模型使用多線程響應(yīng)請(qǐng)求,這樣子存在一個(gè)問題,即一個(gè)線程崩潰就會(huì)影響整個(gè)進(jìn)程.所以worker使用的是多進(jìn)程+多線程的混合模型.即可以提高并發(fā)性,也可以避免一個(gè)線程崩潰導(dǎo)致整個(gè)整個(gè)web站點(diǎn)崩潰.
同prefork一樣,worker中子進(jìn)程跟線程數(shù)量也收到apache配置文件的控制.有如下參數(shù)
MinSpareThreads最少空閑線程
ThreadsPerChild每個(gè)子進(jìn)程可以創(chuàng)建的線程數(shù)量
MaxClients同時(shí)可以處理的請(qǐng)求數(shù)
.....
其web服務(wù)調(diào)優(yōu)大抵就是根據(jù)服務(wù)器配置調(diào)節(jié)這些參數(shù).具體參數(shù)細(xì)節(jié)可以參考Apache文檔
Eventevent模型是在apache2.2之后當(dāng)做試驗(yàn)特性引入的,在apache2.4之后才正式支持.event模型是為了解決長連接(keep-alive)問題而生的.使用worker模型,一個(gè)線程對(duì)應(yīng)一個(gè)請(qǐng)求,當(dāng)一個(gè)請(qǐng)求為長連接的時(shí)候,線程就會(huì)保持當(dāng)長連接狀態(tài),等待客戶端的下一個(gè)請(qǐng)求.這樣子當(dāng)前線程就不能處理其他客戶端請(qǐng)求了.
event模型跟worker模型很像,也是多個(gè)進(jìn)程+多個(gè)線程的混合模式,但是event模型下每個(gè)進(jìn)程會(huì)有一個(gè)多帶帶的線程來管理這些keep-alive類型的線程.當(dāng)新的請(qǐng)求過來的時(shí)候,管理線程會(huì)把請(qǐng)求交給其他的空閑線程處理.這樣子就避免了每個(gè)線程都被keep-alive阻塞.
但是event模型并不是所有情況都通用,在https協(xié)議下會(huì)退化成worker模型.具體原因可以看官方文檔.
Nginx講到Apache,不得不提起現(xiàn)在Nginx.相比于Apache.Nginx于2004年正式發(fā)布.而Apache在1995就已經(jīng)出現(xiàn)了.當(dāng)時(shí)的web環(huán)境還只是簡單的展示靜態(tài)頁面,而且并發(fā)量遠(yuǎn)沒有現(xiàn)在這么高.所以當(dāng)時(shí)Apache的prefork模型也可以很好的承擔(dān)web服務(wù)需求.加之其穩(wěn)定性好,沒有什么理由不用它.
當(dāng)時(shí)后來互聯(lián)網(wǎng)漸漸變大,網(wǎng)站的并發(fā)量變大,Apache就出現(xiàn)了一個(gè)C10K的問題.即一個(gè)物理服務(wù)器達(dá)到并發(fā)量1W的時(shí)候apache就會(huì)承受不了.后來2004年Nginx很好的解決了C10K問題.Nginx為何能優(yōu)于apache解決C10K問題,我們還是得從其處理請(qǐng)求模型說起.
Nginx有三個(gè)著名的特性:
事件驅(qū)動(dòng)編程
異步
非IO阻塞
正是這三種編程方式促使Nginx可以有如此高的并發(fā)量.下面來分析下Nginx到底是如何工作的.
同樣,Nginx的進(jìn)程也分為master進(jìn)程跟worker子進(jìn)程.(其實(shí)還有兩個(gè)cache有關(guān)的進(jìn)程, 這里略過).在啟動(dòng)nginx之后,master進(jìn)程就會(huì)隨即創(chuàng)建一定數(shù)量的worker子進(jìn)程,并且之后worker子進(jìn)程數(shù)量保持不變.并且這些worker子進(jìn)程都是單線程的.當(dāng)一個(gè)請(qǐng)求到來時(shí),worker進(jìn)程中某一個(gè)空閑進(jìn)程就會(huì)去處理這個(gè)請(qǐng)求.乍一看到這里nginx的工作模式跟apache沒有什么區(qū)別.關(guān)鍵就在于nginx如何處理用戶請(qǐng)求.
worker子進(jìn)程開始處理請(qǐng)求.這個(gè)請(qǐng)求可能是訪問某個(gè)網(wǎng)站的靜態(tài)頁面.而html頁面都是保存在硬盤上的.站在操作系統(tǒng)角度來看,nginx是沒有辦法直接讀取硬盤上的文件,必須由nginx告訴操作系統(tǒng)需要讀取哪個(gè)文件,然后又操作系統(tǒng)去讀取這個(gè)文件,讀取完畢操作系統(tǒng)再交給nginx.也就是說,在操作系統(tǒng)讀取文件的時(shí)候,nginx是空閑的.如果是apache,那這個(gè)時(shí)候apache的worker進(jìn)程/線程就阻塞在這里等待操作系統(tǒng)把文件讀取好再交個(gè)自己,這種就稱之為IO阻塞.
但是nginx不一樣, nginx的worker進(jìn)程在這個(gè)時(shí)候就會(huì)注冊(cè)一個(gè)事件,相當(dāng)于告訴操作系統(tǒng):你文件讀好了跟我說一下,我先去處理其他事情.然后這個(gè)worker就可以去處理新的用戶請(qǐng)求了.這里nginx的worker進(jìn)程并沒有由于操作系統(tǒng)讀取文件而阻塞等待,這種即稱之為非IO阻塞
當(dāng)操作系統(tǒng)讀取好文件之后,就會(huì)通知ngixn:我文件幫你讀取好了,你過來拿走."操作系統(tǒng)讀取好文件"這個(gè)事件被觸發(fā)了,于是Nginx就跑回去把文件拿走,然后返回響應(yīng).這種由于某個(gè)事件出現(xiàn)觸發(fā)Nginx執(zhí)行操作的方式就稱為事件驅(qū)動(dòng)編程.
我們回顧上面過程,一個(gè)用戶請(qǐng)求讀取文件,nginx把讀取文件這個(gè)事情通知操作系統(tǒng)之后就去處理下一個(gè)用戶請(qǐng)求,直到操作系統(tǒng)讀取好文件之后再返回響應(yīng).這種一個(gè)請(qǐng)求還沒有處理完畢就去處理下一個(gè)請(qǐng)求的編程方式即異步編程
正是由于nginx這種工作模型,使得nginx在保持一定量的worker進(jìn)程下,也可以得到相當(dāng)大的并發(fā)量.這點(diǎn)正是nginx優(yōu)于apache的地方.同樣,nginx的這種請(qǐng)求處理模型在處理長連接的時(shí)候也可以使用.
Use Both那么是不是說Nginx一定就優(yōu)于Apache.Apache就藥丸了呢.也不是.一定要記住,一個(gè)后來者的出現(xiàn), 沒有在它的前輩所擅長的領(lǐng)域打敗它,那么后來者是不可能完全取代前者.很有可能的情況是兩者并存.nginx本身并不能處理php,python等腳本語言,只能把這些動(dòng)態(tài)請(qǐng)求通過CGI轉(zhuǎn)發(fā)給其他程序處理.所以現(xiàn)在通常的架構(gòu)是前臺(tái)Ngixn負(fù)責(zé)處理靜態(tài)文件諸如js,css,image文件.而碰到請(qǐng)求php等動(dòng)態(tài)內(nèi)容.就在后端多個(gè)apache服務(wù)器中選擇一個(gè)比較空閑的服務(wù)器,把這請(qǐng)求轉(zhuǎn)發(fā)給這個(gè)服務(wù)器處理.等apache處理好之后把返回交給nginx.nginx再返回給用戶.這是目前典型的一種設(shè)計(jì)方案.上面的流程中nginx負(fù)責(zé)兩個(gè)功能:反向代理,負(fù)載均衡.這也是nginx所擅長的兩個(gè)功能.而apache豐富的模塊可以很好的滿足一個(gè)站點(diǎn)的各種需求.并且經(jīng)過了20+年的考驗(yàn),Apache的穩(wěn)定性也是可以保證的.
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/39394.html
摘要:全稱是多道處理模塊我們都知道是以模塊化方式設(shè)計(jì)的那么用來決定如何處理用戶請(qǐng)求的是通過一個(gè)進(jìn)程處理一個(gè)請(qǐng)求還是一個(gè)線程處理一個(gè)請(qǐng)求當(dāng)前有三種可以選擇的方式雖然有以上三種方式但是要注意在任何時(shí)間必須有一個(gè)而且只能有一個(gè)被使用那么下面就介紹一下這 MPM全稱是多道處理模塊,我們都知道apache是以模塊化方式設(shè)計(jì)的.那么MPM用來決定apache如何處理用戶請(qǐng)求的.是通過一個(gè)進(jìn)程處理一個(gè)請(qǐng)...
摘要:但是,反過來卻是不可能的服務(wù)器端發(fā)生了一個(gè)事件,服務(wù)器無法將這個(gè)事件的信息實(shí)時(shí)主動(dòng)通知它的客戶端。這種做法是無奈之舉,實(shí)際上對(duì)服務(wù)器客戶端雙方都造成了大量的性能浪費(fèi)。用于發(fā)送,用戶接受。 HTTP HTTP無法輕松實(shí)現(xiàn)實(shí)時(shí)應(yīng)用: HTTP協(xié)議是無狀態(tài)的,服務(wù)器只會(huì)響應(yīng)來自客戶端的請(qǐng)求,但是它與客戶端之間不具備持續(xù)連接。 我們可以非常輕松的捕獲瀏覽器上發(fā)生的事件(比如用戶點(diǎn)擊了盒子),...
摘要:是環(huán)境下的一款程序調(diào)試工具,用來監(jiān)察一個(gè)應(yīng)用程序所使用的系統(tǒng)調(diào)用及它所接收的系統(tǒng)信息。追蹤程序運(yùn)行時(shí)的整個(gè)生命周期,輸出每一個(gè)系統(tǒng)調(diào)用的名字,參數(shù),返回值和執(zhí)行消耗的時(shí)間等。設(shè)置打印的字符串最大長度。使用某個(gè)用戶或組來運(yùn)行命令。 strace strace是Linux環(huán)境下的一款程序調(diào)試工具,用來監(jiān)察一個(gè)應(yīng)用程序所使用的系統(tǒng)調(diào)用及它所接收的系統(tǒng)信息。追蹤程序運(yùn)行時(shí)的整個(gè)生命周期,輸出每...
一,通過 nginx -t可以找到當(dāng)前的nginx的加載的配置文件的地址nginx-t nginx:theconfigurationfile/etc/nginx/nginx.confsyntaxisok nginx:configurationfile/etc/nginx/nginx.conftestissuccessful 二,通過 ps -ef|grep nginx可以很簡單的看到當(dāng)前的...
閱讀 3331·2021-09-07 10:10
閱讀 3645·2019-08-30 15:44
閱讀 2653·2019-08-30 15:44
閱讀 3123·2019-08-29 15:11
閱讀 2291·2019-08-28 18:26
閱讀 2805·2019-08-26 12:21
閱讀 1178·2019-08-23 16:12
閱讀 3141·2019-08-23 14:57