讀《深入理解nginx》&《nginx開發(fā)從入門到精通》后的幾點解惑

[toc]

0.前言

從開始使用nginx到現(xiàn)在至少也有六年多的時間,一直停留在應(yīng)用的層面上,這次抽了一個多星期的時間簡單看了一下這兩本書。本文不能說是對于nginx 的解析,在長期對nginx的模糊認識的情況下又有了更深的認識。包括對于master-worker的認識,對于nginx 使用epoll 事件模型的理解等。另外又看了一些應(yīng)用層面的配置。
以下記錄了幾點簡單的知識點,貼了一些鏈接都是在看書時產(chǎn)生的問題,搜索之后找到比較滿意答案的鏈接。依舊是看得多記得少。長期更新。

1.Nginx應(yīng)用層面問題

1.1 pid文件的作用

記錄Master 進程id,通過cli 向master進程發(fā)送信號,操控運行中的nginx。

1.2 worker進程數(shù)的設(shè)置

worker的進程數(shù)設(shè)置為cpu核心數(shù)相等時,進程間切換的代價還是最小的。

https://www.centos.bz/2016/10/tweaking-nginx-conguration/

1.3 非守護進程運行

daemon on | off;

注意docker 下 daemon 需要設(shè)置為off.否則無法啟動成功.詳見

https://segmentfault.com/a/1190000009583997

1.4 帶有@的location

不直接處理用戶請求,用于處內(nèi)部請求重定向
理解為其他location轉(zhuǎn)發(fā).

1.5 try_files的應(yīng)用

不是一個問題,但是繼續(xù)強調(diào)一下.
單頁應(yīng)用中(spa)路由跳轉(zhuǎn)重定向到index.html

location / {
        try_files $uri $uri/ /index.html;
    } 

2.Nginx如何處理HTTP 請求

https://www.kancloud.cn/digest/understandingnginx/202586
https://www.cnblogs.com/jimodetiantang/p/8952141.html
https://blog.csdn.net/xiajun07061225/article/details/9260535

2.1 請求處理

https://tengine.taobao.org/book/chapter_02.html#id12

nginx使用一個多進程模型來對外提供服務(wù),其中一個master進程,多個worker進程。master進程負責(zé)管理nginx本身和其他worker進程。

所有實際上的業(yè)務(wù)處理邏輯都在worker進程。worker進程中有一個函數(shù),執(zhí)行無限循環(huán),不斷處理收到的來自客戶端的請求,并進行處理,直到整個nginx服務(wù)被停止。

worker進程中,ngx_worker_process_cycle()函數(shù)就是這個無限循環(huán)的處理函數(shù)。在這個函數(shù)中,一個請求的簡單處理流程如下:

  • 操作系統(tǒng)提供的機制(例如epoll, kqueue等)產(chǎn)生相關(guān)的事件。
  • 接收和處理這些事件,如是接受到數(shù)據(jù),則產(chǎn)生更高層的request對象。
  • 處理request的header和body。
  • 產(chǎn)生響應(yīng),并發(fā)送回客戶端。
  • 完成request的處理。
  • 重新初始化定時器及其他事件。

2.2 處理流程

  • 初始化HTTP Request(讀取來自客戶端的數(shù)據(jù),生成HTTP Request對象,該對象含有該請求所有的信息)。
  • 處理請求頭。
  • 處理請求體。
  • 如果有的話,調(diào)用與此請求(URL或者Location)關(guān)聯(lián)的handler。
  • 依次調(diào)用各phase handler進行處理。

2.3 為何高效

https://blog.csdn.net/russell_tao/article/details/7160071

epoll模型
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);
int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);

  • 鏈表記錄監(jiān)聽句柄,可以監(jiān)聽更多的文件句柄。
  • epoll_wait 近返回有事件發(fā)生的句柄,減少從系統(tǒng)態(tài)復(fù)制到用戶態(tài)的數(shù)據(jù)。

為什么nginx可以采用異步非阻塞的方式來處理呢,或者異步非阻塞到底是怎么回事呢?我們先回到原點,看看一個請求的完整過程。首先,請求過來,要建立連接,然后再接收數(shù)據(jù),接收數(shù)據(jù)后,再發(fā)送數(shù)據(jù)。具體到系統(tǒng)底層,就是讀寫事件,而當(dāng)讀寫事件沒有準(zhǔn)備好時,必然不可操作,如果不用非阻塞的方式來調(diào)用,那就得阻塞調(diào)用了,事件沒有準(zhǔn)備好,那就只能等了,等事件準(zhǔn)備好了,你再繼續(xù)吧。阻塞調(diào)用會進入內(nèi)核等待,cpu就會讓出去給別人用了,對單線程的worker來說,顯然不合適,當(dāng)網(wǎng)絡(luò)事件越多時,大家都在等待呢,cpu空閑下來沒人用,cpu利用率自然上不去了,更別談高并發(fā)了。好吧,你說加進程數(shù),這跟apache的線程模型有什么區(qū)別,注意,別增加無謂的上下文切換。所以,在nginx里面,最忌諱阻塞的系統(tǒng)調(diào)用了。不要阻塞,那就非阻塞嘍。非阻塞就是,事件沒有準(zhǔn)備好,馬上返回EAGAIN,告訴你,事件還沒準(zhǔn)備好呢,你慌什么,過會再來吧。好吧,你過一會,再來檢查一下事件,直到事件準(zhǔn)備好了為止,在這期間,你就可以先去做其它事情,然后再來看看事件好了沒。雖然不阻塞了,但你得不時地過來檢查一下事件的狀態(tài),你可以做更多的事情了,但帶來的開銷也是不小的。所以,才會有了異步非阻塞的事件處理機制,具體到系統(tǒng)調(diào)用就是像select/poll/epoll/kqueue這樣的系統(tǒng)調(diào)用。它們提供了一種機制,讓你可以同時監(jiān)控多個事件,調(diào)用他們是阻塞的,但可以設(shè)置超時時間,在超時時間之內(nèi),如果有事件準(zhǔn)備好了,就返回。這種機制正好解決了我們上面的兩個問題,拿epoll為例(在后面的例子中,我們多以epoll為例子,以代表這一類函數(shù)),當(dāng)事件沒準(zhǔn)備好時,放到epoll里面,事件準(zhǔn)備好了,我們就去讀寫,當(dāng)讀寫返回EAGAIN時,我們將它再次加入到epoll里面。這樣,只要有事件準(zhǔn)備好了,我們就去處理它,只有當(dāng)所有事件都沒準(zhǔn)備好時,才在epoll里面等著。這樣,我們就可以并發(fā)處理大量的并發(fā)了,當(dāng)然,這里的并發(fā)請求,是指未處理完的請求,線程只有一個,所以同時能處理的請求當(dāng)然只有一個了,只是在請求間進行不斷地切換而已,切換也是因為異步事件未準(zhǔn)備好,而主動讓出的。這里的切換是沒有任何代價,你可以理解為循環(huán)處理多個準(zhǔn)備好的事件,事實上就是這樣的。與多線程相比,這種事件處理方式是有很大的優(yōu)勢的,不需要創(chuàng)建線程,每個請求占用的內(nèi)存也很少,沒有上下文切換,事件處理非常的輕量級。并發(fā)數(shù)再多也不會導(dǎo)致無謂的資源浪費(上下文切換)。更多的并發(fā)數(shù),只是會占用更多的內(nèi)存而已。 我之前有對連接數(shù)進行過測試,在24G內(nèi)存的機器上,處理的并發(fā)請求數(shù)達到過200萬?,F(xiàn)在的網(wǎng)絡(luò)服務(wù)器基本都采用這種方式,這也是nginx性能高效的主要原因。

定時器實現(xiàn)

https://russelltao.iteye.com/blog/1405352

  1. 將未完成的連接處理放入超時管理中,超時未完成剔除,避免無效連接占用資源。
  2. 超時對象的組織形式采用紅黑樹,提供較高性能的刪除和插入操作.
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Nginx才短短幾年,就拿下了web服務(wù)器大筆江山,眾所周知,Nginx在處理大并發(fā)靜態(tài)請求方面,效率明顯高于ht...
    松江野人閱讀 1,171評論 0 2
  • 眾所周知,nginx性能高,而nginx的高性能與其架構(gòu)是分不開的。那么nginx究竟是怎么樣的呢?這一節(jié)我們先來...
    Alfie20閱讀 1,697評論 2 4
  • 情商的核心內(nèi)容可以用以下四句話描述: 知道別人的情緒,知道自己的情緒, 尊重別人的情緒,調(diào)控自己的情緒。 人的素質(zhì)...
    每文_5197閱讀 481評論 1 1
  • 午后 初秋清風(fēng)拂過 擺弄著你的發(fā)鬢 竟然無端嫉妒起風(fēng)來 我的角度 只能看見你側(cè)臉 溫馨的像湖畔的風(fēng)景 會與這個世界...
    深藍海閱讀 243評論 0 4
  • 身邊跟我年齡相仿的人大都結(jié)婚生子了。也有很多親戚在催促我趕緊找個對我好的人嫁了,這樣一輩子也就算成功一大半了。 可...
    沫言之閱讀 464評論 0 0

友情鏈接更多精彩內(nèi)容