一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Apache與Nginx網(wǎng)絡(luò)模型

 牽牛吃草 2016-06-30

      Nginx的高并發(fā)得益于其采用了epoll模型,與傳統(tǒng)的服務(wù)器程序架構(gòu)不同,epoll是linux內(nèi)核2.6以后才出現(xiàn)的。下面通過比較Apache和Nginx工作原理來比較。

 

      傳統(tǒng)Apache都是多進(jìn)程或者多線程來工作,假設(shè)是多進(jìn)程工作(prefork),apache會(huì)先生成幾個(gè)進(jìn)程,類似進(jìn)程池的工作原理,只不過這里的進(jìn)程池會(huì)隨著請(qǐng)求數(shù)目的增加而增加。對(duì)于每一個(gè)連接,apache都是在一個(gè)進(jìn)程內(nèi)處理完畢。具體是 recv(),以及根據(jù) URI 去進(jìn)行磁盤I/O來尋找文件,還有 send()都是阻塞的。其實(shí)說白了都是 apche 對(duì)于套接字的I/O,讀或者寫,但是讀或者寫都是阻塞的,阻塞意味著進(jìn)程就得掛起進(jìn)入sleep狀態(tài),那么一旦連接數(shù)很多,Apache必然要生成更多的進(jìn)程來響應(yīng)請(qǐng)求,一旦進(jìn)程多了,CPU對(duì)于進(jìn)程的切換就頻繁了,很耗資源和時(shí)間,所以就導(dǎo)致apache性能下降了,說白了就是處理不過來這么多進(jìn)程了。其實(shí)仔細(xì)想想,如果對(duì)于進(jìn)程每個(gè)請(qǐng)求都沒有阻塞,那么效率肯定會(huì)提高很多。

 

      Nginx采用epoll模型,異步非阻塞。對(duì)于Nginx來說,把一個(gè)完整的連接請(qǐng)求處理都劃分成了事件,一個(gè)一個(gè)的事件。比如accept(), recv(),磁盤I/O,send()等,每部分都有相應(yīng)的模塊去處理,一個(gè)完整的請(qǐng)求可能是由幾百個(gè)模塊去處理。真正核心的就是事件收集和分發(fā)模塊,這就是管理所有模塊的核心。只有核心模塊的調(diào)度才能讓對(duì)應(yīng)的模塊占用CPU資源,從而處理請(qǐng)求。拿一個(gè)HTTP請(qǐng)求來說,首先在事件收集分發(fā)模塊注冊(cè)感興趣的監(jiān)聽事件,注冊(cè)好之后不阻塞直接返回,接下來就不需要再管了,等待有連接來了內(nèi)核會(huì)通知你(epoll的輪詢會(huì)告訴進(jìn)程),cpu就可以處理其他事情去了。一旦有請(qǐng)求來,那么對(duì)整個(gè)請(qǐng)求分配相應(yīng)的上下文(其實(shí)已經(jīng)預(yù)先分配好),這時(shí)候再注冊(cè)新的感興趣的事件(read函數(shù)),同樣客戶端數(shù)據(jù)來了內(nèi)核會(huì)自動(dòng)通知進(jìn)程可以去讀數(shù)據(jù)了,讀了數(shù)據(jù)之后就是解析,解析完后去磁盤找資源(I/O),一旦I/O完成會(huì)通知進(jìn)程,進(jìn)程開始給客戶端發(fā)回?cái)?shù)據(jù)send(),這時(shí)候也不是阻塞的,調(diào)用后就等內(nèi)核發(fā)回通知發(fā)送的結(jié)果就行。整個(gè)下來把一個(gè)請(qǐng)求分成了很多個(gè)階段,每個(gè)階段都到很多模塊去注冊(cè),然后處理,都是異步非阻塞。異步這里指的就是做一個(gè)事情,不需要等返回結(jié)果,做好了會(huì)自動(dòng)通知你。

select/epoll的特點(diǎn)

select的特點(diǎn):select 選擇句柄的時(shí)候,是遍歷所有句柄,也就是說句柄有事件響應(yīng)時(shí),select需要遍歷所有句柄才能獲取到哪些句柄有事件通知,因此效率是非常低。但是如果連接很少的情況下, select和epoll的LT觸發(fā)模式相比, 性能上差別不大。
這里要多說一句,select支持的句柄數(shù)是有限制的, 同時(shí)只支持1024個(gè),這個(gè)是句柄集合限制的,如果超過這個(gè)限制,很可能導(dǎo)致溢出,而且非常不容易發(fā)現(xiàn)問題, 當(dāng)然可以通過修改linux的socket內(nèi)核調(diào)整這個(gè)參數(shù)。
epoll的特點(diǎn):epoll對(duì)于句柄事件的選擇不是遍歷的,是事件響應(yīng)的,就是句柄上事件來就馬上選擇出來,不需要遍歷整個(gè)句柄鏈表,因此效率非常高,內(nèi)核將句柄用紅黑樹保存的。
對(duì)于epoll而言還有ET和LT的區(qū)別,LT表示水平觸發(fā),ET表示邊緣觸發(fā),兩者在性能以及代碼實(shí)現(xiàn)上差別也是非常大的。

 Epoll模型主要負(fù)責(zé)對(duì)大量并發(fā)用戶的請(qǐng)求進(jìn)行及時(shí)處理,完成服務(wù)器與客戶端的數(shù)據(jù)交互。其具體的實(shí)現(xiàn)步驟如下:
(a) 使用epoll_create()函數(shù)創(chuàng)建文件描述,設(shè)定將可管理的最大socket描述符數(shù)目。
(b) 創(chuàng)建與epoll關(guān)聯(lián)的接收線程,應(yīng)用程序可以創(chuàng)建多個(gè)接收線程來處理epoll上的讀通知事件,線程的數(shù)量依賴于程序的具體需要。
(c) 創(chuàng)建一個(gè)偵聽socket描述符ListenSock;將該描述符設(shè)定為非阻塞模式,調(diào)用Listen()函數(shù)在套接字上偵聽有無新的連接請(qǐng)求,在 epoll_event結(jié)構(gòu)中設(shè)置要處理的事件類型EPOLLIN,工作方式為 epoll_ET,以提高工作效率,同時(shí)使用epoll_ctl()注冊(cè)事件,最后啟動(dòng)網(wǎng)絡(luò)監(jiān)視線程。
(d) 網(wǎng)絡(luò)監(jiān)視線程啟動(dòng)循環(huán),epoll_wait()等待epoll事件發(fā)生。
(e) 如果epoll事件表明有新的連接請(qǐng)求,則調(diào)用accept()函數(shù),將用戶socket描述符添加到epoll_data聯(lián)合體,同時(shí)設(shè)定該描述符為非 阻塞,并在epoll_event結(jié)構(gòu)中設(shè)置要處理的事件類型為讀和寫,工作方式為epoll_ET.
(f) 如果epoll事件表明socket描述符上有數(shù)據(jù)可讀,則將該socket描述符加入可讀隊(duì)列,通知接收線程讀入數(shù)據(jù),并將接收到的數(shù)據(jù)放入到接收數(shù)據(jù) 的鏈表中,經(jīng)邏輯處理后,將反饋的數(shù)據(jù)包放入到發(fā)送數(shù)據(jù)鏈表中,等待由發(fā)送線程發(fā)送。

epoll的操作就這么簡(jiǎn)單,總共不過4個(gè) API:epoll_create, epoll_ctl, epoll_wait和close。

      可以舉一個(gè)簡(jiǎn)單的例子來說明Apache的工作流程,我們平時(shí)去餐廳吃飯。餐廳的工作模式是一個(gè)服務(wù)員全程服務(wù)客戶,流程是這樣,服務(wù)員在門口等候客人(listen),客人到了就接待安排的餐桌上(accept),等著客戶點(diǎn)菜(request uri),去廚房叫師傅下單做菜(磁盤I/O),等待廚房做好(read),然后給客人上菜(send),整個(gè)下來服務(wù)員(進(jìn)程)很多地方是阻塞的。這樣客人一多(HTTP請(qǐng)求一多),餐廳只能通過叫更多的服務(wù)員來服務(wù)(fork進(jìn)程),但是由于餐廳資源是有限的(CPU),一旦服務(wù)員太多管理成本很高(CPU上下文切換),這樣就進(jìn)入一個(gè)瓶頸。
再來看看Nginx得怎么處理?餐廳門口掛個(gè)門鈴(注冊(cè)epoll模型的listen),一旦有客人(HTTP請(qǐng)求)到達(dá),派一個(gè)服務(wù)員去接待(accept),之后服務(wù)員就去忙其他事情了(比如再去接待客人),等這位客人點(diǎn)好餐就叫服務(wù)員(數(shù)據(jù)到了read()),服務(wù)員過來拿走菜單到廚房(磁盤I/O),服務(wù)員又做其他事情去了,等廚房做好了菜也喊服務(wù)員(磁盤I/O結(jié)束),服務(wù)員再給客人上菜(send()),廚房做好一個(gè)菜就給客人上一個(gè),中間服務(wù)員可以去干其他事情。整個(gè)過程被切分成很多個(gè)階段,每個(gè)階段都有相應(yīng)的服務(wù)模塊。我們想想,這樣一旦客人多了,餐廳也能招待更多的人。

        不管是Nginx還是Squid這種反向代理,其網(wǎng)絡(luò)模式都是事件驅(qū)動(dòng)。事件驅(qū)動(dòng)其實(shí)是很老的技術(shù),早期的select、poll都是如此。后來基于內(nèi)核通知的更高級(jí)事件機(jī)制出現(xiàn),如libevent里的epoll,使事件驅(qū)動(dòng)性能得以提高。事件驅(qū)動(dòng)的本質(zhì)還是IO事件,應(yīng)用程序在多個(gè)IO句柄間快速切換,實(shí)現(xiàn)所謂的異步IO。事件驅(qū)動(dòng)服務(wù)器,最適合做的就是這種IO密集型工作,如反向代理,它在客戶端與WEB服務(wù)器之間起一個(gè)數(shù)據(jù)中轉(zhuǎn)作用,純粹是IO操作,自身并不涉及到復(fù)雜計(jì)算。反向代理用事件驅(qū)動(dòng)來做,顯然更好,一個(gè)工作進(jìn)程就可以run了,沒有進(jìn)程、線程管理的開銷,CPU、內(nèi)存消耗都小。

  所以Nginx、Squid都是這樣做的。當(dāng)然,Nginx也可以是多進(jìn)程 + 事件驅(qū)動(dòng)的模式,幾個(gè)進(jìn)程跑libevent,不需要Apache那樣動(dòng)輒數(shù)百的進(jìn)程數(shù)。Nginx處理靜態(tài)文件效果也很好,那是因?yàn)殪o態(tài)文件本身也是磁盤IO操作,處理過程一樣。至于說多少萬的并發(fā)連接,這個(gè)毫無意義。隨手寫個(gè)網(wǎng)絡(luò)程序都能處理幾萬的并發(fā),但如果大部分客戶端阻塞在那里,就沒什么價(jià)值。

  再看看Apache或者Resin這類應(yīng)用服務(wù)器,之所以稱他們?yōu)閼?yīng)用服務(wù)器,是因?yàn)樗麄冋娴囊芫唧w的業(yè)務(wù)應(yīng)用,如科學(xué)計(jì)算、圖形圖像、數(shù)據(jù)庫讀寫等。它們很可能是CPU密集型的服務(wù),事件驅(qū)動(dòng)并不合適。例如一個(gè)計(jì)算耗時(shí)2秒,那么這2秒就是完全阻塞的,什么event都沒用。想想MySQL如果改成事件驅(qū)動(dòng)會(huì)怎么樣,一個(gè)大型的join或sort就會(huì)阻塞住所有客戶端。這個(gè)時(shí)候多進(jìn)程或線程就體現(xiàn)出優(yōu)勢(shì),每個(gè)進(jìn)程各干各的事,互不阻塞和干擾。當(dāng)然,現(xiàn)代CPU越來越快,單個(gè)計(jì)算阻塞的時(shí)間可能很小,但只要有阻塞,事件編程就毫無優(yōu)勢(shì)。所以進(jìn)程、線程這類技術(shù),并不會(huì)消失,而是與事件機(jī)制相輔相成,長(zhǎng)期存在。

  總言之,事件驅(qū)動(dòng)適合于IO密集型服務(wù),多進(jìn)程或線程適合于CPU密集型服務(wù),它們各有各的優(yōu)勢(shì),并不存在誰取代誰的傾向。

 

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    欧美极品欧美精品欧美| 午夜精品国产一区在线观看| 欧美乱码精品一区二区三| 日韩精品日韩激情日韩综合| 亚洲欧美日本国产不卡| 黑鬼糟蹋少妇资源在线观看| 日韩精品在线观看一区| 人妻一区二区三区在线| 正在播放玩弄漂亮少妇高潮| 少妇人妻一级片一区二区三区| 日韩av亚洲一区二区三区| 儿媳妇的诱惑中文字幕| 激情少妇一区二区三区| 国内欲色一区二区三区| 激情国产白嫩美女在线观看| 亚洲国产av在线观看一区| 欧美又黑又粗大又硬又爽| 隔壁的日本人妻中文字幕版| 国产成人国产精品国产三级 | 国产免费一区二区不卡| 色丁香一区二区黑人巨大| 亚洲精品一区三区三区| 久久国产精品亚州精品毛片 | 成人免费视频免费观看| 免费观看在线午夜视频| 日韩不卡一区二区在线| 精品国产一区二区欧美| 少妇淫真视频一区二区| 五月天丁香婷婷狠狠爱| 五月综合激情婷婷丁香| 欧美日韩亚洲巨色人妻| 中文字幕在线五月婷婷| 91欧美日韩精品在线| 亚洲国产成人久久99精品| 国产黑人一区二区三区| 欧美国产极品一区二区| 精品熟女少妇av免费久久野外| 在线欧洲免费无线码二区免费| 欧美精品一区久久精品| 午夜午夜精品一区二区| 成人三级视频在线观看不卡|