如果說(shuō)nginx比Apache性能高是因?yàn)閚ginx用的c,那用匯編寫的性能豈不是更好?
網(wǎng)友解答: 快不快和語(yǔ)言關(guān)系不大,快的原因得益于nginx的epoll模型 apache是多線程或者多進(jìn)程,在工作的時(shí)候,當(dāng)來(lái)了一個(gè)http響應(yīng),一個(gè)進(jìn)程接收(listen)–識(shí)別處理
快不快和語(yǔ)言關(guān)系不大,快的原因得益于nginx的epoll模型 apache是多線程或者多進(jìn)程,在工作的時(shí)候,當(dāng)來(lái)了一個(gè)http響應(yīng),一個(gè)進(jìn)程接收(listen)–識(shí)別處理—返回請(qǐng)求,在此過程中,一個(gè)進(jìn)程全部處理,apche 對(duì)于套接字的I/O,讀或者寫,但是讀或者寫都是阻塞的,阻塞意味著進(jìn)程就得掛起進(jìn)入sleep狀態(tài),那么一旦連接數(shù)很多,Apache必然要生成更多的進(jìn)程來(lái)響應(yīng)請(qǐng)求,一旦進(jìn)程多了,CPU對(duì)于進(jìn)程的切換就頻繁了,很耗資源和時(shí)間,所以就導(dǎo)致apache性能下降了,說(shuō)白了就是處理不過來(lái)這么多進(jìn)程了。
Nginx采用epoll模型,異步非阻塞。對(duì)于Nginx來(lái)說(shuō),把一個(gè)完整的連接請(qǐng)求處理都劃分成了事件,一個(gè)一個(gè)的事件。比如accept(), receive(),磁盤I/O,send()等,每部分都有相應(yīng)的模塊去處理,一個(gè)完整的請(qǐng)求可能是由幾百個(gè)模塊去處理。真正核心的就是事件收集和分發(fā)模塊,這就是管理所有模塊的核心。只有核心模塊的調(diào)度才能讓對(duì)應(yīng)的模塊占用CPU資源,從而處理請(qǐng)求。拿一個(gè)HTTP請(qǐng)求來(lái)說(shuō),首先在事件收集分發(fā)模塊注冊(cè)感興趣的監(jiān)聽事件,注冊(cè)好之后不阻塞直接返回,接下來(lái)就不需要再管了,等待有連接來(lái)了內(nèi)核會(huì)通知你(epoll的輪詢會(huì)告訴進(jìn)程),cpu就可以處理其他事情去了。一旦有請(qǐng)求來(lái),那么對(duì)整個(gè)請(qǐng)求分配相應(yīng)的上下文(其實(shí)已經(jīng)預(yù)先分配好),這時(shí)候再注冊(cè)新的感興趣的事件(read函數(shù)),同樣客戶端數(shù)據(jù)來(lái)了內(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è)下來(lái)把一個(gè)請(qǐng)求分成了很多個(gè)階段,每個(gè)階段都到很多模塊去注冊(cè),然后處理,都是異步非阻塞。異步這里指的就是做一個(gè)事情,不需要等返回結(jié)果,做好了會(huì)自動(dòng)通知你。