nginx源码阅读(一).综述
前言
nginx作為一款開源的輕量級(jí)高性能web服務(wù)器,是非常值得立志從事服務(wù)端開發(fā)方向的人學(xué)習(xí)的。現(xiàn)今nginx的最新版本是nginx-1.13.6,代碼量也日漸龐大,但是由于其核心思想并沒改變,為了降低閱讀難度,我選擇的是nginx-1.0.15版本,并且由于時(shí)間和水平有限,重點(diǎn)關(guān)注的是nginx的啟動(dòng)以及進(jìn)程模型、事件模塊中的epoll模塊、負(fù)載均衡以及整體的框架等方面。
這里先推薦兩本有關(guān)nginx的書籍:《深入理解Nginx》、《深入剖析Nginx》,后者已經(jīng)絕版了,可以去網(wǎng)上找pdf閱讀。
不過建議主要還是以代碼為主,書籍為輔。
下面簡(jiǎn)單的介紹一下后面會(huì)進(jìn)行分析的各塊。
nginx的啟動(dòng)
nginx整個(gè)啟動(dòng)流程圍繞著ngx_cycle_t結(jié)構(gòu)體進(jìn)行操作。要知道nginx是高度模塊化以及非常依賴配置文件,大部分功能都需要配置文件的配置才能進(jìn)行。在啟動(dòng)工作中,需要做的主要工作就是讀取配置文件,然后將各模塊感興趣的配置項(xiàng)保存到各結(jié)構(gòu)體中,根據(jù)配置文件對(duì)所有的模塊進(jìn)行初始化,接著啟動(dòng)各進(jìn)程,準(zhǔn)備進(jìn)行工作。
nginx的多進(jìn)程模型
另一款比較常用的web服務(wù)器就是apache,它最大的特點(diǎn)就是穩(wěn)定,所以相比于nginx復(fù)雜很多也臃腫很多。nginx最大的特點(diǎn)就是強(qiáng)調(diào)性能,在后面展示其源碼時(shí)也可以看到它為了追求性能所做的一些工作。
nginx之所以高效的主要原因是它采用的異步非阻塞多進(jìn)程模型,并且一般進(jìn)程的個(gè)數(shù)與cpu核心數(shù)相同,一個(gè)master進(jìn)程,多個(gè)worker進(jìn)程,可能還會(huì)有cache loader以及cache manager進(jìn)程,多個(gè)連接對(duì)應(yīng)一個(gè)worker進(jìn)程,master進(jìn)程主要負(fù)責(zé)管理worker進(jìn)程以及啟動(dòng)/停止服務(wù)、重新讀取配置文件、平滑升級(jí)等功能,而cache進(jìn)程則當(dāng)開啟了緩存功能才會(huì)出現(xiàn)。
apache則通常采用同步多進(jìn)程模型,每個(gè)連接對(duì)應(yīng)一個(gè)進(jìn)程,apache采用的這種模型,當(dāng)請(qǐng)求較多時(shí),進(jìn)程也隨之變多,cpu資源耗費(fèi)在進(jìn)程間切換非常昂貴(畢竟要切換進(jìn)程的上下文以及重載緩存等),而nginx因?yàn)檫M(jìn)程數(shù)固定且很少,并且由于cpu是多核心的,可以同時(shí)運(yùn)行多個(gè)不同的進(jìn)程/線程,每個(gè)進(jìn)程的資源都互相獨(dú)立,因此切換時(shí)無需進(jìn)行上下文的切換。那么為什么不采用多線程結(jié)構(gòu)呢,不是說線程間的切換比進(jìn)程間的切換更迅速嗎,若cpu是單核的的確如此,但是當(dāng)每個(gè)cpu核心運(yùn)行一個(gè)線程的時(shí)候,由于線程間需要共享資源,所以這些資源必須從一個(gè)核心拷貝到另外一個(gè)核心,反觀多進(jìn)程就不需要。因此在cpu為多核的情況下,多線程在性能上反而可能不如多進(jìn)程。
關(guān)于同步和異步的區(qū)別,可以簡(jiǎn)單的理解為,采用同步模型,cpu會(huì)阻塞等待請(qǐng)求的完成,而異步非阻塞時(shí),cpu不會(huì)阻塞等待,內(nèi)核處理完之后再進(jìn)行通知。
nginx的事件模塊
nginx采用的是事件驅(qū)動(dòng)機(jī)制來處理事件,不同的模塊有各自己負(fù)責(zé)處理的事件,當(dāng)一個(gè)事件發(fā)生時(shí),相應(yīng)的模塊就會(huì)對(duì)該事件進(jìn)行處理。對(duì)于一個(gè)web服務(wù)器來說,用戶的請(qǐng)求其實(shí)就對(duì)應(yīng)了一個(gè)tcp連接,也對(duì)應(yīng)了讀/寫事件,nginx內(nèi)部使用了連接池、內(nèi)存池等機(jī)制提高效率,而nginx的事件模塊中針對(duì)不同的I/O多路機(jī)制select、epoll、kqueue、eventport也編寫了不同的模塊,這是為了能讓nginx在更多的操作系統(tǒng)上運(yùn)行。在linux下,我們重點(diǎn)關(guān)注的就是epoll對(duì)應(yīng)的模塊,nginx對(duì)epoll提供的接口進(jìn)行了封裝,并且將定時(shí)事件也集成到了其中。
負(fù)載均衡
nginx有兩處地方進(jìn)行了負(fù)載均衡。一處是當(dāng)大量的請(qǐng)求到來時(shí),各個(gè)worker進(jìn)程該如何分配這些請(qǐng)求,而不會(huì)造成其中某個(gè)worker進(jìn)程超載,而另外的worker進(jìn)程則空閑,nginx采用的是負(fù)載均衡鎖,當(dāng)一個(gè)worker進(jìn)程處理的連接數(shù)大于某個(gè)值時(shí),就不再接受新的連接。
還有一處是當(dāng)nginx作為反向代理服務(wù)器運(yùn)行時(shí),會(huì)將客戶端的請(qǐng)求轉(zhuǎn)發(fā)給上游服務(wù)器,若上游服務(wù)器有多個(gè),則需要選擇將請(qǐng)求轉(zhuǎn)發(fā)給哪個(gè)上游服務(wù)器,一直轉(zhuǎn)給一個(gè)造成其中某個(gè)服務(wù)器過載,但是其余空閑肯定是不對(duì)。nginx官方提供了加權(quán)輪詢、IP哈希這兩種負(fù)載均衡的方法。加權(quán)輪詢簡(jiǎn)單的來說就是計(jì)算各個(gè)上游服務(wù)器的權(quán)值,然后選擇權(quán)值最高的服務(wù)器處理請(qǐng)求;IP哈希負(fù)載均衡策略則會(huì)使用客戶端的ip地址作為哈希的key來決定選擇服務(wù)器群中某臺(tái)服務(wù)器來處理客戶端的請(qǐng)求,這種方式可以確保來自同一臺(tái)客戶端的請(qǐng)求會(huì)分發(fā)到同一臺(tái)服務(wù)器上,除非這臺(tái)服務(wù)器處于不可用狀態(tài)。
除了這兩種方法之外,還有一致哈希、fair等方法,不過都是第三方模塊。
整體架構(gòu)
nginx即可以處理靜態(tài)請(qǐng)求也可以處理動(dòng)態(tài)請(qǐng)求,并且還可以作為反向代理服務(wù)器。但是它處理動(dòng)態(tài)請(qǐng)求的效果并不如apache好,因此一般作為靜態(tài)web服務(wù)器和反向代理服務(wù)器。整體的架構(gòu)引用《深入剖析Nginx》書中的圖:
小結(jié)
本小節(jié)簡(jiǎn)單的介紹了一下后面要展開分析的各塊,接下來正式開始分析nginx的啟動(dòng)流程。
--------------------- 作者:Move_now 來源:CSDN 原文:https://blog.csdn.net/Move_now/article/details/78373017?utm_source=copy 版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!
總結(jié)
以上是生活随笔為你收集整理的nginx源码阅读(一).综述的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 成都欢乐谷刺激项目身高限制
- 下一篇: 龙票剧情介绍