版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
深入理解Nginx模塊開發(fā)與架構(gòu)解析目錄\h第一部分Nginx能幫我們做什么\h第1章研究Nginx前的準(zhǔn)備工作\h1.1Nginx是什么\h1.2為什么選擇Nginx\h1.3準(zhǔn)備工作\h1.4編譯安裝Nginx\h1.5configure詳解\h1.6Nginx的命令行控制\h1.7小結(jié)\h第2章Nginx的配置\h2.1運行中的Nginx進程間的關(guān)系\h2.2Nginx配置的通用語法\h2.3Nginx服務(wù)的基本配置\h2.4用HTTP核心模塊配置一個靜態(tài)Web服務(wù)器\h2.5用HTTPproxymodule配置一個反向代理服務(wù)器\h2.6小結(jié)\h第二部分如何編寫HTTP模塊\h第3章開發(fā)一個簡單的HTTP模塊\h3.1如何調(diào)用HTTP模塊\h3.2準(zhǔn)備工作\h3.3如何將自己的HTTP模塊編譯進Nginx\h3.4HTTP模塊的數(shù)據(jù)結(jié)構(gòu)\h3.5定義自己的HTTP模塊\h3.6處理用戶請求\h3.7發(fā)送響應(yīng)\h3.8將磁盤文件作為包體發(fā)送\h3.9用C++語言編寫HTTP模塊\h3.10小結(jié)\h第4章配置、error日志和請求上下文\h4.1http配置項的使用場景\h4.2怎樣使用http配置\h4.3HTTP配置模型\h4.4error日志的用法\h4.5請求的上下文\h4.6小結(jié)\h第5章訪問第三方服務(wù)\h5.1upstream的使用方式\h5.2回調(diào)方法的執(zhí)行場景\h5.3使用upstream的示例\h5.4subrequest的使用方式\h5.5subrequest執(zhí)行過程中的主要場景\h5.6subrequest使用的例子\h5.7小結(jié)\h第6章開發(fā)一個簡單的HTTP過濾模塊\h6.1過濾模塊的意義\h6.2過濾模塊的調(diào)用順序\h6.3HTTP過濾模塊的開發(fā)步驟\h6.4HTTP過濾模塊的簡單例子\h6.5小結(jié)\h第7章Nginx提供的高級數(shù)據(jù)結(jié)構(gòu)\h7.1Nginx提供的高級數(shù)據(jù)結(jié)構(gòu)概述\h7.2ngx_queue_t雙向鏈表\h7.3ngx_array_t動態(tài)數(shù)組\h7.4ngx_list_t單向鏈表\h7.5ngx_rbtree_t紅黑樹\h7.6ngx_radix_tree_t基數(shù)樹\h7.7支持通配符的散列表\h7.8小結(jié)\h第三部分深入Nginx\h第8章Nginx基礎(chǔ)架構(gòu)\h8.1Web服務(wù)器設(shè)計中的關(guān)鍵約束\h8.2Nginx的架構(gòu)設(shè)計\h8.3Nginx框架中的核心結(jié)構(gòu)體ngx_cycle_t\h8.4Nginx啟動時框架的處理流程\h8.5worker進程是如何工作的\h8.6master進程是如何工作的\h8.7ngx_pool_t內(nèi)存池\h8.8小結(jié)\h第9章事件模塊\h9.1事件處理框架概述\h9.2Nginx事件的定義\h9.3Nginx連接的定義\h9.4ngx_events_module核心模塊\h9.5ngx_event_core_module事件模塊\h9.6epoll事件驅(qū)動模塊\h9.7定時器事件\h9.8事件驅(qū)動框架的處理流程\h9.9文件的異步I/O\h9.10TCP協(xié)議與Nginx\h9.11小結(jié)\h第10章HTTP框架的初始化\h10.1HTTP框架概述\h10.2管理HTTP模塊的配置項\h10.3監(jiān)聽端口的管理\h10.4server的快速檢索\h10.5location的快速檢索\h10.6HTTP請求的11個處理階段\h10.7HTTP框架的初始化流程\h10.8小結(jié)\h第11章HTTP框架的執(zhí)行流程\h11.1HTTP框架執(zhí)行流程概述\h11.2新連接建立時的行為\h11.3第一次可讀事件的處理\h11.4接收HTTP請求行\(zhòng)h11.5接收HTTP頭部\h11.6處理HTTP請求\h11.7subrequest與post請求\h11.8處理HTTP包體\h11.9發(fā)送HTTP響應(yīng)\h11.10結(jié)束HTTP請求\h11.11小結(jié)\h第12章upstream機制的設(shè)計與實現(xiàn)\h12.1upstream機制概述\h12.2啟動upstream\h12.3與上游服務(wù)器建立連接\h12.4發(fā)送請求到上游服務(wù)器\h12.5接收上游服務(wù)器的響應(yīng)頭部\h12.6不轉(zhuǎn)發(fā)響應(yīng)時的處理流程\h12.7以下游網(wǎng)速優(yōu)先來轉(zhuǎn)發(fā)響應(yīng)\h12.8以上游網(wǎng)速優(yōu)先來轉(zhuǎn)發(fā)響應(yīng)\h12.9結(jié)束upstream請求\h12.10小結(jié)\h第13章郵件代理模塊\h13.1郵件代理服務(wù)器的功能\h13.2郵件模塊的處理框架\h13.3初始化請求\h13.4接收并解析客戶端請求\h13.5郵件認證\h13.6與上游郵件服務(wù)器間的認證交互\h13.7透傳上游郵件服務(wù)器與客戶端間的流\h13.8小結(jié)\h第14章進程間的通信機制\h14.1概述\h14.2共享內(nèi)存\h14.3原子操作\h14.4Nginx頻道\h14.5信號\h14.6信號量\h14.7文件鎖\h14.8互斥鎖\h14.9小結(jié)\h第15章變量\h15.1使用內(nèi)部變量開發(fā)模塊\h15.2內(nèi)部變量工作原理\h15.3定義內(nèi)部變量\h15.4外部變量與腳本引擎\h15.5小結(jié)\h第16章slab共享內(nèi)存\h16.1操作slab共享內(nèi)存的方法\h16.2使用slab共享內(nèi)存池的例子\h16.3slab內(nèi)存管理的實現(xiàn)原理\h16.4小結(jié)注:原文檔電子版(非掃描),需要的請下載本文檔后留言謝謝。第一部分Nginx能幫我們做什么·第1章研究Nginx前的準(zhǔn)備工作·第2章Nginx的配置第1章研究Nginx前的準(zhǔn)備工作2012年,Nginx榮獲年度云計算開發(fā)獎(2012CloudAwardforDeveloperoftheYear),并成長為世界第二大Web服務(wù)器。全世界流量最高的前1000名網(wǎng)站中,超過25%都使用Nginx來處理海量的互聯(lián)網(wǎng)請求。Nginx已經(jīng)成為業(yè)界高性能Web服務(wù)器的代名詞。那么,什么是Nginx?它有哪些特點?我們選擇Nginx的理由是什么?如何編譯安裝Nginx?這種安裝方式背后隱藏的又是什么樣的思想呢?本章將會回答上述問題。1.1Nginx是什么人們在了解新事物時,往往習(xí)慣通過類比來幫助自己理解事物的概貌。那么,我們在學(xué)習(xí)Nginx時也采用同樣的方式,先來看看Nginx的競爭對手——Apache、Lighttpd、Tomcat、Jetty、IIS,它們都是Web服務(wù)器,或者叫做WWW(WorldWideWeb)服務(wù)器,相應(yīng)地也都具備Web服務(wù)器的基本功能:基于REST架構(gòu)風(fēng)格,以統(tǒng)一資源描述符(UniformResourceIdentifier,URI)或者統(tǒng)一資源定位符(UniformResourceLocator,URL)作為溝通依據(jù),通過HTTP為瀏覽器等客戶端程序提供各種網(wǎng)絡(luò)服務(wù)。然而,由于這些Web服務(wù)器在設(shè)計階段就受到許多局限,例如當(dāng)時的互聯(lián)網(wǎng)用戶規(guī)模、網(wǎng)絡(luò)帶寬、產(chǎn)品特點等局限,并且各自的定位與發(fā)展方向都不盡相同,使得每一款Web服務(wù)器的特點與應(yīng)用場合都很鮮明。Tomcat和Jetty面向Java語言,先天就是重量級的Web服務(wù)器,它的性能與Nginx沒有可比性,這里略過。IIS只能在Windows操作系統(tǒng)上運行。Windows作為服務(wù)器在穩(wěn)定性與其他一些性能上都不如類UNIX操作系統(tǒng),因此,在需要高性能Web服務(wù)器的場合下,IIS可能會被“冷落”。Apache的發(fā)展時期很長,而且是目前毫無爭議的世界第一大Web服務(wù)器,圖1-1中是12年來(2010~2012年)世界Web服務(wù)器的使用排名情況。圖1-1Netcraft對于644275754個站點31.4M個域名Web服務(wù)器使用情況的調(diào)查結(jié)果(2012年3月)從圖1-1中可以看出,Apache目前處于領(lǐng)先地位。Apache有許多優(yōu)點,如穩(wěn)定、開源、跨平臺等,但它出現(xiàn)的時間太長了,在它興起的年代,互聯(lián)網(wǎng)的產(chǎn)業(yè)規(guī)模遠遠比不上今天,所以它被設(shè)計成了一個重量級的、不支持高并發(fā)的Web服務(wù)器。在Apache服務(wù)器上,如果有數(shù)以萬計的并發(fā)HTTP請求同時訪問,就會導(dǎo)致服務(wù)器上消耗大量內(nèi)存,操作系統(tǒng)內(nèi)核對成百上千的Apache進程做進程間切換也會消耗大量CPU資源,并導(dǎo)致HTTP請求的平均響應(yīng)速度降低,這些都決定了Apache不可能成為高性能Web服務(wù)器,這也促使了Lighttpd和Nginx的出現(xiàn)。觀察圖1-1中Nginx成長的曲線,體會一下Nginx搶占市場時的“咄咄逼人”吧。Lighttpd和Nginx一樣,都是輕量級、高性能的Web服務(wù)器,歐美的業(yè)界開發(fā)者比較鐘愛Lighttpd,而國內(nèi)的公司更青睞Nginx,Lighttpd使用得比較少。在了解了Nginx的競爭對手之后,相信大家對Nginx也有了直觀感受,下面讓我們來正式地認識一下Nginx吧。提示Nginx發(fā)音:engine。來自俄羅斯的IgorSysoev在為RamblerMedia(http://www.rambler.ru/)工作期間,使用C語言開發(fā)了Nginx。Nginx作為Web服務(wù)器,一直為俄羅斯著名的門戶網(wǎng)站RamblerMedia提供著出色、穩(wěn)定的服務(wù)。IgorSysoev將Nginx的代碼開源,并且賦予其最自由的2-clauseBSD-likelicense許可證。由于Nginx使用基于事件驅(qū)動的架構(gòu)能夠并發(fā)處理百萬級別的TCP連接,高度模塊化的設(shè)計和自由的許可證使得擴展Nginx功能的第三方模塊層出不窮,而且優(yōu)秀的設(shè)計帶來了極佳的穩(wěn)定性,因此其作為Web服務(wù)器被廣泛應(yīng)用到大流量的網(wǎng)站上,包括騰訊、新浪、網(wǎng)易、淘寶等訪問量巨大的網(wǎng)站。2012年2月和3月Netcraft對Web服務(wù)器的調(diào)查如表1-1所示,可以看出,Nginx的市場份額越來越大。表1-1Netcraft對于Web服務(wù)器市場占有率前4位軟件的調(diào)查(2012年2月和3月)Nginx是一個跨平臺的Web服務(wù)器,可運行在Linux、FreeBSD、Solaris、AIX、MacOS、Windows等操作系統(tǒng)上,并且它還可以使用當(dāng)前操作系統(tǒng)特有的一些高效API來提高自己的性能。例如,對于高效處理大規(guī)模并發(fā)連接,它支持Linux上的epoll(epoll是Linux上處理大并發(fā)網(wǎng)絡(luò)連接的利器,9.6.1節(jié)中將會詳細說明epoll的工作原理)、Solaris上的eventports和FreeBSD上的kqueue等。又如,對于Linux,Nginx支持其獨有的sendfile系統(tǒng)調(diào)用,這個系統(tǒng)調(diào)用可以高效地把硬盤中的數(shù)據(jù)發(fā)送到網(wǎng)絡(luò)上(不需要先把硬盤數(shù)據(jù)復(fù)制到用戶態(tài)內(nèi)存上再發(fā)送),這極大地減少了內(nèi)核態(tài)與用戶態(tài)數(shù)據(jù)間的復(fù)制動作。種種跡象都表明,Nginx以性能為王。2011年7月,Nginx正式成立公司,由IgorSysoev擔(dān)任CTO,立足于提供商業(yè)級的Web服務(wù)器。1.2為什么選擇Nginx為什么選擇Nginx?因為它具有以下特點:(1)更快這表現(xiàn)在兩個方面:一方面,在正常情況下,單次請求會得到更快的響應(yīng);另一方面,在高峰期(如有數(shù)以萬計的并發(fā)請求),Nginx可以比其他Web服務(wù)器更快地響應(yīng)請求。實際上,本書第三部分中大量的篇幅都是在說明Nginx是如何做到這兩點的。(2)高擴展性Nginx的設(shè)計極具擴展性,它完全是由多個不同功能、不同層次、不同類型且耦合度極低的模塊組成。因此,當(dāng)對某一個模塊修復(fù)Bug或進行升級時,可以專注于模塊自身,無須在意其他。而且在HTTP模塊中,還設(shè)計了HTTP過濾器模塊:一個正常的HTTP模塊在處理完請求后,會有一串HTTP過濾器模塊對請求的結(jié)果進行再處理。這樣,當(dāng)我們開發(fā)一個新的HTTP模塊時,不但可以使用諸如HTTP核心模塊、events模塊、log模塊等不同層次或者不同類型的模塊,還可以原封不動地復(fù)用大量已有的HTTP過濾器模塊。這種低耦合度的優(yōu)秀設(shè)計,造就了Nginx龐大的第三方模塊,當(dāng)然,公開的第三方模塊也如官方發(fā)布的模塊一樣容易使用。Nginx的模塊都是嵌入到二進制文件中執(zhí)行的,無論官方發(fā)布的模塊還是第三方模塊都是如此。這使得第三方模塊一樣具備極其優(yōu)秀的性能,充分利用Nginx的高并發(fā)特性,因此,許多高流量的網(wǎng)站都傾向于開發(fā)符合自己業(yè)務(wù)特性的定制模塊。(3)高可靠性高可靠性是我們選擇Nginx的最基本條件,因為Nginx的可靠性是大家有目共睹的,很多家高流量網(wǎng)站都在核心服務(wù)器上大規(guī)模使用Nginx。Nginx的高可靠性來自于其核心框架代碼的優(yōu)秀設(shè)計、模塊設(shè)計的簡單性;另外,官方提供的常用模塊都非常穩(wěn)定,每個worker進程相對獨立,master進程在1個worker進程出錯時可以快速“拉起”新的worker子進程提供服務(wù)。(4)低內(nèi)存消耗一般情況下,10000個非活躍的HTTPKeep-Alive連接在Nginx中僅消耗2.5MB的內(nèi)存,這是Nginx支持高并發(fā)連接的基礎(chǔ)。從第3章開始,我們會接觸到Nginx在內(nèi)存中為了維護一個HTTP連接所分配的對象,屆時將會看到,實際上Nginx一直在為用戶考慮(尤其是在高并發(fā)時)如何使得內(nèi)存的消耗更少。(5)單機支持10萬以上的并發(fā)連接這是一個非常重要的特性!隨著互聯(lián)網(wǎng)的迅猛發(fā)展和互聯(lián)網(wǎng)用戶數(shù)量的成倍增長,各大公司、網(wǎng)站都需要應(yīng)付海量并發(fā)請求,一個能夠在峰值期頂住10萬以上并發(fā)請求的Server,無疑會得到大家的青睞。理論上,Nginx支持的并發(fā)連接上限取決于內(nèi)存,10萬遠未封頂。當(dāng)然,能夠及時地處理更多的并發(fā)請求,是與業(yè)務(wù)特點緊密相關(guān)的,本書第8~11章將會詳細說明如何實現(xiàn)這個特點。(6)熱部署master管理進程與worker工作進程的分離設(shè)計,使得Nginx能夠提供熱部署功能,即可以在7×24小時不間斷服務(wù)的前提下,升級Nginx的可執(zhí)行文件。當(dāng)然,它也支持不停止服務(wù)就更新配置項、更換日志文件等功能。(7)最自由的BSD許可協(xié)議這是Nginx可以快速發(fā)展的強大動力。BSD許可協(xié)議不只是允許用戶免費使用Nginx,它還允許用戶在自己的項目中直接使用或修改Nginx源碼,然后發(fā)布。這吸引了無數(shù)開發(fā)者繼續(xù)為Nginx貢獻自己的智慧。以上7個特點當(dāng)然不是Nginx的全部,擁有無數(shù)個官方功能模塊、第三方功能模塊使得Nginx能夠滿足絕大部分應(yīng)用場景,這些功能模塊間可以疊加以實現(xiàn)更加強大、復(fù)雜的功能,有些模塊還支持Nginx與Perl、Lua等腳本語言集成工作,大大提高了開發(fā)效率。這些特點促使用戶在尋找一個Web服務(wù)器時更多考慮Nginx。當(dāng)然,選擇Nginx的核心理由還是它能在支持高并發(fā)請求的同時保持高效的服務(wù)。如果Web服務(wù)器的業(yè)務(wù)訪問量巨大,就需要保證在數(shù)以百萬計的請求同時訪問服務(wù)時,用戶可以獲得良好的體驗,不會出現(xiàn)并發(fā)訪問量達到一個數(shù)字后,新的用戶無法獲取服務(wù),或者雖然成功地建立起了TCP連接,但大部分請求卻得不到響應(yīng)的情況。通常,高峰期服務(wù)器的訪問量可能是正常情況下的許多倍,若有熱點事件的發(fā)生,可能會導(dǎo)致正常情況下非常順暢的服務(wù)器直接“掛死”。然而,如果在部署服務(wù)器時,就預(yù)先針對這種情況進行擴容,又會使得正常情況下所有服務(wù)器的負載過低,這會造成大量的資源浪費。因此,我們會希望在這之間取得平衡,也就是說,在低并發(fā)壓力下,用戶可以獲得高速體驗,而在高并發(fā)壓力下,更多的用戶都能接入,可能訪問速度會下降,但這只應(yīng)受制于帶寬和處理器的速度,而不應(yīng)該是服務(wù)器設(shè)計導(dǎo)致的軟件瓶頸。事實上,由于中國互聯(lián)網(wǎng)用戶群體的數(shù)量巨大,致使對Web服務(wù)器的設(shè)計往往要比歐美公司更加困難。例如,對于全球性的一些網(wǎng)站而言,歐美用戶分布在兩個半球,歐洲用戶活躍時,美洲用戶通常在休息,反之亦然。而國內(nèi)巨大的用戶群體則對業(yè)界的程序員提出更高的挑戰(zhàn),早上9點和晚上20點到24點這些時間段的并發(fā)請求壓力是非常巨大的。尤其節(jié)假日、寒暑假到來之時,更會對服務(wù)器提出極高的要求。另外,國內(nèi)業(yè)務(wù)上的特性,也會引導(dǎo)用戶在同一時間大并發(fā)地訪問服務(wù)器。例如,許多SNS網(wǎng)頁游戲會在固定的時間點刷新游戲資源或者允許“偷菜”等好友互動操作。這些會導(dǎo)致服務(wù)器處理高并發(fā)請求的壓力增大。上述情形都對我們的互聯(lián)網(wǎng)服務(wù)在大并發(fā)壓力下是否還能夠給予用戶良好的體驗提出了更高的要求。若要提供更好的服務(wù),那么可以從多方面入手,例如,修改業(yè)務(wù)特性、引導(dǎo)用戶從高峰期分流或者把服務(wù)分層分級、對于不同并發(fā)壓力給用戶提供不同級別的服務(wù)等。但最根本的是,Web服務(wù)器要能支持大并發(fā)壓力下的正常服務(wù),這才是關(guān)鍵??焖僭鲩L的互聯(lián)網(wǎng)用戶群以及業(yè)內(nèi)所有互聯(lián)網(wǎng)服務(wù)提供商越來越好的用戶體驗,都促使我們在大流量服務(wù)中用Nginx取代其他Web服務(wù)器。Nginx先天的事件驅(qū)動型設(shè)計、全異步的網(wǎng)絡(luò)I/O處理機制、極少的進程間切換以及許多優(yōu)化設(shè)計,都使得Nginx天生善于處理高并發(fā)壓力下的互聯(lián)網(wǎng)請求,同時Nginx降低了資源消耗,可以把服務(wù)器硬件資源“壓榨”到極致。1.3準(zhǔn)備工作由于Linux具有免費、使用廣泛、商業(yè)支持越來越完善等特點,本書將主要針對Linux上運行的Nginx來進行介紹。需要說明的是,本書不是使用手冊,而是介紹Nginx作為Web服務(wù)器的設(shè)計思想,以及如何更有效地使用Nginx達成目的,而這些內(nèi)容在各操作系統(tǒng)上基本是相通的(除了第9章關(guān)于事件驅(qū)動方式以及第14章的進程間同步方式在類UNIX操作系統(tǒng)上略有不同以外)。1.3.1Linux操作系統(tǒng)首先我們需要一個內(nèi)核為Linux2.6及以上版本的操作系統(tǒng),因為Linux2.6及以上內(nèi)核才支持epoll,而在Linux上使用select或poll來解決事件的多路復(fù)用,是無法解決高并發(fā)壓力問題的。我們可以使用uname-a命令來查詢Linux內(nèi)核版本,例如::wehf2wng001:root>uname-aLinuxwehf2wng0012.6.18-128.el5#1SMPWedJan2110:41:14EST2009x86_64x86_64x86_64GNU/Linux執(zhí)行結(jié)果表明內(nèi)核版本是2.6.18,符合我們的要求。1.3.2使用Nginx的必備軟件如果要使用Nginx的常用功能,那么首先需要確保該操作系統(tǒng)上至少安裝了如下軟件。(1)GCC編譯器GCC(GNUCompilerCollection)可用來編譯C語言程序。Nginx不會直接提供二進制可執(zhí)行程序(1.2.x版本中已經(jīng)開始提供某些操作系統(tǒng)上的二進制安裝包了,不過,本書探討如何開發(fā)Nginx模塊是必須通過直接編譯源代碼進行的),這有許多原因,本章后面會詳述。我們可以使用最簡單的yum方式安裝GCC,例如:yuminstall-ygccGCC是必需的編譯工具。在第3章會提到如何使用C++來編寫NginxHTTP模塊,這時就需要用到G++編譯器了。G++編譯器也可以用yum安裝,例如:yuminstall-ygcc-c++Linux上有許多軟件安裝方式,yum只是其中比較方便的一種,其他方式這里不再贅述。(2)PCRE庫PCRE(PerlCompatibleRegularExpressions,Perl兼容正則表達式)是由PhilipHazel開發(fā)的函數(shù)庫,目前為很多軟件所使用,該庫支持正則表達式。它由RegEx演化而來,實際上,Perl正則表達式也是源自于HenrySpencer寫的RegEx。如果我們在配置文件nginx.conf里使用了正則表達式,那么在編譯Nginx時就必須把PCRE庫編譯進Nginx,因為Nginx的HTTP模塊要靠它來解析正則表達式。當(dāng)然,如果你確認不會使用正則表達式,就不必安裝它。其yum安裝方式如下:yuminstall-ypcrepcre-develpcre-devel是使用PCRE做二次開發(fā)時所需要的開發(fā)庫,包括頭文件等,這也是編譯Nginx所必須使用的。(3)zlib庫zlib庫用于對HTTP包的內(nèi)容做gzip格式的壓縮,如果我們在nginx.conf里配置了gzipon,并指定對于某些類型(content-type)的HTTP響應(yīng)使用gzip來進行壓縮以減少網(wǎng)絡(luò)傳輸量,那么,在編譯時就必須把zlib編譯進Nginx。其yum安裝方式如下:yuminstall-yzlibzlib-devel同理,zlib是直接使用的庫,zlib-devel是二次開發(fā)所需要的庫。(4)OpenSSL開發(fā)庫如果我們的服務(wù)器不只是要支持HTTP,還需要在更安全的SSL協(xié)議上傳輸HTTP,那么就需要擁有OpenSSL了。另外,如果我們想使用MD5、SHA1等散列函數(shù),那么也需要安裝它。其yum安裝方式如下:yuminstall-yopensslopenssl-devel上面所列的4個庫只是完成Web服務(wù)器最基本功能所必需的。Nginx是高度自由化的Web服務(wù)器,它的功能是由許多模塊來支持的。而這些模塊可根據(jù)我們的使用需求來定制,如果某些模塊不需要使用則完全不必理會它。同樣,如果使用了某個模塊,而這個模塊使用了一些類似zlib或OpenSSL等的第三方庫,那么就必須先安裝這些軟件。1.3.3磁盤目錄要使用Nginx,還需要在Linux文件系統(tǒng)上準(zhǔn)備以下目錄。(1)Nginx源代碼存放目錄該目錄用于放置從官網(wǎng)上下載的Nginx源碼文件,以及第三方或我們自己所寫的模塊源代碼文件。(2)Nginx編譯階段產(chǎn)生的中間文件存放目錄該目錄用于放置在configure命令執(zhí)行后所生成的源文件及目錄,以及make命令執(zhí)行后生成的目標(biāo)文件和最終連接成功的二進制文件。默認情況下,configure命令會將該目錄命名為objs,并放在Nginx源代碼目錄下。(3)部署目錄該目錄存放實際Nginx服務(wù)運行期間所需要的二進制文件、配置文件等。默認情況下,該目錄為/usr/local/nginx。(4)日志文件存放目錄日志文件通常會比較大,當(dāng)研究Nginx的底層架構(gòu)時,需要打開debug級別的日志,這個級別的日志非常詳細,會導(dǎo)致日志文件的大小增長得極快,需要預(yù)先分配一個擁有更大磁盤空間的目錄。1.3.4Linux內(nèi)核參數(shù)的優(yōu)化由于默認的Linux內(nèi)核參數(shù)考慮的是最通用的場景,這明顯不符合用于支持高并發(fā)訪問的Web服務(wù)器的定義,所以需要修改Linux內(nèi)核參數(shù),使得Nginx可以擁有更高的性能。在優(yōu)化內(nèi)核時,可以做的事情很多,不過,我們通常會根據(jù)業(yè)務(wù)特點來進行調(diào)整,當(dāng)Nginx作為靜態(tài)Web內(nèi)容服務(wù)器、反向代理服務(wù)器或是提供圖片縮略圖功能(實時壓縮圖片)的服務(wù)器時,其內(nèi)核參數(shù)的調(diào)整都是不同的。這里只針對最通用的、使Nginx支持更多并發(fā)請求的TCP網(wǎng)絡(luò)參數(shù)做簡單說明。首先,需要修改/etc/sysctl.conf來更改內(nèi)核參數(shù)。例如,最常用的配置:fs.file-max=999999net.ipv4.tcp_tw_reuse=1net.ipv4.tcp_keepalive_time=600net.ipv4.tcp_fin_timeout=30net.ipv4.tcp_max_tw_buckets=5000net.ipv4.ip_local_port_range=102461000net.ipv4.tcp_rmem=409632768262142net.ipv4.tcp_wmem=409632768262142dev_max_backlog=8096net.core.rmem_default=262144net.core.wmem_default=262144net.core.rmem_max=2097152net.core.wmem_max=2097152net.ipv4.tcp_syncookies=1net.ipv4.tcp_max_syn.backlog=1024然后執(zhí)行sysctl-p命令,使上述修改生效。上面的參數(shù)意義解釋如下:·file-max:這個參數(shù)表示進程(比如一個worker進程)可以同時打開的最大句柄數(shù),這個參數(shù)直接限制最大并發(fā)連接數(shù),需根據(jù)實際情況配置。·tcp_tw_reuse:這個參數(shù)設(shè)置為1,表示允許將TIME-WAIT狀態(tài)的socket重新用于新的TCP連接,這對于服務(wù)器來說很有意義,因為服務(wù)器上總會有大量TIME-WAIT狀態(tài)的連接?!cp_keepalive_time:這個參數(shù)表示當(dāng)keepalive啟用時,TCP發(fā)送keepalive消息的頻度。默認是2小時,若將其設(shè)置得小一些,可以更快地清理無效的連接?!cp_fin_timeout:這個參數(shù)表示當(dāng)服務(wù)器主動關(guān)閉連接時,socket保持在FIN-WAIT-2狀態(tài)的最大時間?!cp_max_tw_buckets:這個參數(shù)表示操作系統(tǒng)允許TIME_WAIT套接字數(shù)量的最大值,如果超過這個數(shù)字,TIME_WAIT套接字將立刻被清除并打印警告信息。該參數(shù)默認為180000,過多的TIME_WAIT套接字會使Web服務(wù)器變慢?!cp_max_syn_backlog:這個參數(shù)表示TCP三次握手建立階段接收SYN請求隊列的最大長度,默認為1024,將其設(shè)置得大一些可以使出現(xiàn)Nginx繁忙來不及accept新連接的情況時,Linux不至于丟失客戶端發(fā)起的連接請求?!p_local_port_range:這個參數(shù)定義了在UDP和TCP連接中本地(不包括連接的遠端)端口的取值范圍?!et.ipv4.tcp_rmem:這個參數(shù)定義了TCP接收緩存(用于TCP接收滑動窗口)的最小值、默認值、最大值。·net.ipv4.tcp_wmem:這個參數(shù)定義了TCP發(fā)送緩存(用于TCP發(fā)送滑動窗口)的最小值、默認值、最大值?!etdev_max_backlog:當(dāng)網(wǎng)卡接收數(shù)據(jù)包的速度大于內(nèi)核處理的速度時,會有一個隊列保存這些數(shù)據(jù)包。這個參數(shù)表示該隊列的最大值?!mem_default:這個參數(shù)表示內(nèi)核套接字接收緩存區(qū)默認的大小?!mem_default:這個參數(shù)表示內(nèi)核套接字發(fā)送緩存區(qū)默認的大小?!mem_max:這個參數(shù)表示內(nèi)核套接字接收緩存區(qū)的最大大小。·wmem_max:這個參數(shù)表示內(nèi)核套接字發(fā)送緩存區(qū)的最大大小。注意滑動窗口的大小與套接字緩存區(qū)會在一定程度上影響并發(fā)連接的數(shù)目。每個TCP連接都會為維護TCP滑動窗口而消耗內(nèi)存,這個窗口會根據(jù)服務(wù)器的處理速度收縮或擴張。參數(shù)wmem_max的設(shè)置,需要平衡物理內(nèi)存的總大小、Nginx并發(fā)處理的最大連接數(shù)量(由nginx.conf中的worker_processes和worker_connections參數(shù)決定)而確定。當(dāng)然,如果僅僅為了提高并發(fā)量使服務(wù)器不出現(xiàn)OutOfMemory問題而去降低滑動窗口大小,那么并不合適,因為滑動窗口過小會影響大數(shù)據(jù)量的傳輸速度。rmem_default、wmem_default、rmem_max、wmem_max這4個參數(shù)的設(shè)置需要根據(jù)我們的業(yè)務(wù)特性以及實際的硬件成本來綜合考慮?!cp_syncookies:該參數(shù)與性能無關(guān),用于解決TCP的SYN攻擊。1.3.5獲取Nginx源碼可以在Nginx官方網(wǎng)站(/en/download.html)獲取Nginx源碼包。將下載的nginx-1.0.14.tar.gz源碼壓縮包放置到準(zhǔn)備好的Nginx源代碼目錄中,然后解壓。例如:tar-zxvfnginx-1.0.14.tar.gz本書編寫時的Nginx最新穩(wěn)定版本為1.0.14(如圖1-2所示),本書后續(xù)部分都將以此版本作為基準(zhǔn)。當(dāng)然,本書將要說明的Nginx核心代碼一般不會有改動(否則大量第三方模塊的功能就無法保證了),即使下載其他版本的Nginx源碼包也不會影響閱讀本書。圖1-2Nginx的不同版本1.4編譯安裝Nginx安裝Nginx最簡單的方式是,進入nginx-1.0.14目錄后執(zhí)行以下3行命令:./configuremakemakeinstallconfigure命令做了大量的“幕后”工作,包括檢測操作系統(tǒng)內(nèi)核和已經(jīng)安裝的軟件,參數(shù)的解析,中間目錄的生成以及根據(jù)各種參數(shù)生成一些C源碼文件、Makefile文件等。make命令根據(jù)configure命令生成的Makefile文件編譯Nginx工程,并生成目標(biāo)文件、最終的二進制文件。makeinstall命令根據(jù)configure執(zhí)行時的參數(shù)將Nginx部署到指定的安裝目錄,包括相關(guān)目錄的建立和二進制文件、配置文件的復(fù)制。1.5configure詳解可以看出,configure命令至關(guān)重要,下文將詳細介紹如何使用configure命令,并分析configure到底是如何工作的,從中我們也可以看出Nginx的一些設(shè)計思想。1.5.1configure的命令參數(shù)使用help命令可以查看configure包含的參數(shù)。./configure--help這里不一一列出help的結(jié)果,只是把它的參數(shù)分為了四大類型,下面將會詳述各類型下所有參數(shù)的用法和意義。1.路徑相關(guān)的參數(shù)表1-2列出了Nginx在編譯期、運行期中與路徑相關(guān)的各種參數(shù)。表1-2configure支持的路徑相關(guān)參數(shù)2.編譯相關(guān)的參數(shù)表1-3列出了編譯Nginx時與編譯器相關(guān)的參數(shù)。表1-3configure支持的編譯相關(guān)參數(shù)3.依賴軟件的相關(guān)參數(shù)表1-4~表1-8列出了Nginx依賴的常用軟件支持的參數(shù)。表1-4PCRE的設(shè)置參數(shù)表1-5OpenSSL的設(shè)置參數(shù)表1-6原子庫的設(shè)置參數(shù)表1-7散列函數(shù)庫的設(shè)置參數(shù)表1-8zlib庫的設(shè)置參數(shù)4.模塊相關(guān)的參數(shù)除了少量核心代碼外,Nginx完全是由各種功能模塊組成的。這些模塊會根據(jù)配置參數(shù)決定自己的行為,因此,正確地使用各個模塊非常關(guān)鍵。在configure的參數(shù)中,我們把它們分為五大類?!な录K。·默認即編譯進入Nginx的HTTP模塊?!つJ不會編譯進入Nginx的HTTP模塊。·郵件代理服務(wù)器相關(guān)的mail模塊?!て渌K。(1)事件模塊表1-9中列出了Nginx可以選擇哪些事件模塊編譯到產(chǎn)品中。表1-9configure支持的事件模塊參數(shù)(2)默認即編譯進入Nginx的HTTP模塊表1-10列出了默認就會編譯進Nginx的核心HTTP模塊,以及如何把這些HTTP模塊從產(chǎn)品中去除。表1-10configure中默認編譯到Nginx中的HTTP模塊參數(shù)(3)默認不會編譯進入Nginx的HTTP模塊表1-11列出了默認不會編譯至Nginx中的HTTP模塊以及把它們加入產(chǎn)品中的方法。表1-11configure中默認不會編譯到Nginx中的HTTP模塊參數(shù)(4)郵件代理服務(wù)器相關(guān)的mail模塊表1-12列出了把郵件模塊編譯到產(chǎn)品中的參數(shù)。表1-12configure提供的郵件模塊參數(shù)5.其他參數(shù)configure還接收一些其他參數(shù),表1-13中列出了相關(guān)參數(shù)的說明。表1-13configure提供的其他參數(shù)1.5.2configure執(zhí)行流程我們看到configure命令支持非常多的參數(shù),讀者可能會好奇它在執(zhí)行時到底做了哪些事情,本節(jié)將通過解析configure源碼來對它有一個感性的認識。configure由Shell腳本編寫,中間會調(diào)用/auto/目錄下的腳本。這里將只對configure腳本本身做分析,對于它所調(diào)用的auto目錄下的其他工具腳本則只做功能性的說明。configure腳本的內(nèi)容如下:#!/bin/sh#Copyright(C)IgorSysoev#Copyright(C)Nginx,Inc.#auto/options腳本處理configure命令的參數(shù)。例如,如果參數(shù)是--help,那么顯示支持的所有參數(shù)格式。options腳本會定義后續(xù)工作將要用到的變量,然后根據(jù)本次參數(shù)以及默認值設(shè)置這些變量.auto/options#auto/init腳本初始化后續(xù)將產(chǎn)生的文件路徑。例如,Makefile、ngx_modules.c等文件默認情況下將會在/objs/.auto/init#auto/sources腳本將分析Nginx的源碼結(jié)構(gòu),這樣才能構(gòu)造后續(xù)的Makefile文件.auto/sources#編譯過程中所有目標(biāo)文件生成的路徑由—builddir=DIR參數(shù)指定,默認情況下為/objs,此時這個目錄將會被創(chuàng)建test-d$NGX_OBJS||mkdir$NGX_OBJS#開始準(zhǔn)備建立ngx_auto_headers.h、autoconf.err等必要的編譯文件echo>$NGX_AUTO_HEADERS_Hecho>$NGX_AUTOCONF_ERR#向objs/ngx_auto_config.h寫入命令行帶的參數(shù)echo"#defineNGX_CONFIGURE\"$NGX_CONFIGURE\"">$NGX_AUTO_CONFIG_H#判斷DEBUG標(biāo)志,如果有,那么在objs/ngx_auto_config.h文件中寫入DEBUG宏if[$NGX_DEBUG=YES];thenhave=NGX_DEBUG.auto/havefi#現(xiàn)在開始檢查操作系統(tǒng)參數(shù)是否支持后續(xù)編譯iftest-z"$NGX_PLATFORM";thenecho"checkingforOS"NGX_SYSTEM=`uname-s2>/dev/null`NGX_RELEASE=`uname-r2>/dev/null`NGX_MACHINE=`uname-m2>/dev/null`#屏幕上輸出OS名稱、內(nèi)核版本、32位/64位內(nèi)核echo"+$NGX_SYSTEM$NGX_RELEASE$NGX_MACHINE"NGX_PLATFORM="$NGX_SYSTEM:$NGX_RELEASE:$NGX_MACHINE";case"$NGX_SYSTEM"inMINGW32_*)NGX_PLATFORM=win32;;esacelseecho"buildingfor$NGX_PLATFORM"NGX_SYSTEM=$NGX_PLATFORMfi#檢查并設(shè)置編譯器,如GCC是否安裝、GCC版本是否支持后續(xù)編譯nginx.auto/cc/conf#對非Windows操作系統(tǒng)定義一些必要的頭文件,并檢查其是否存在,以此決定configure后續(xù)步驟是否可以成功if["$NGX_PLATFORM"!=win32];then.auto/headersfi#對于當(dāng)前操作系統(tǒng),定義一些特定的操作系統(tǒng)相關(guān)的方法并檢查當(dāng)前環(huán)境是否支持。例如,對于Linux,在這里使用sched_setaffinity設(shè)置進程優(yōu)先級,使用Linux特有的sendfile系統(tǒng)調(diào)用來加速向網(wǎng)絡(luò)中發(fā)送文件塊.auto/os/conf#定義類UNIX操作系統(tǒng)中通用的頭文件和系統(tǒng)調(diào)用等,并檢查當(dāng)前環(huán)境是否支持if["$NGX_PLATFORM"!=win32];then.auto/unixfi#最核心的構(gòu)造運行期modules的腳本。它將會生成ngx_modules.c文件,這個文件會被編譯進Nginx中,其中它所做的唯一的事情就是定義了ngx_modules數(shù)組。ngx_modules指明Nginx運行期間有哪些模塊會參與到請求的處理中,包括HTTP請求可能會使用哪些模塊處理,因此,它對數(shù)組元素的順序非常敏感,也就是說,絕大部分模塊在ngx_modules數(shù)組中的順序其實是固定的。例如,一個請求必須先執(zhí)行ngx_http_gzip_filter_module模塊重新修改HTTP響應(yīng)中的頭部后,才能使用ngx_http_header_filter模塊按照headers_in結(jié)構(gòu)體里的成員構(gòu)造出以TCP流形式發(fā)送給客戶端的HTTP響應(yīng)頭部。注意,我們在--add-module=參數(shù)里加入的第三方模塊也在此步驟寫入到ngx_modules.c文件中了.auto/modules#conf腳本用來檢查Nginx在鏈接期間需要鏈接的第三方靜態(tài)庫、動態(tài)庫或者目標(biāo)文件是否存在.auto/lib/conf#處理Nginx安裝后的路徑case".$NGX_PREFIX"in.)NGX_PREFIX=${NGX_PREFIX:-/usr/local/nginx}have=NGX_PREFIXvalue="\"$NGX_PREFIX/\"".auto/define;;.!)NGX_PREFIX=;;*)have=NGX_PREFIXvalue="\"$NGX_PREFIX/\"".auto/define;;esac#處理Nginx安裝后conf文件的路徑if[".$NGX_CONF_PREFIX"!="."];thenhave=NGX_CONF_PREFIXvalue="\"$NGX_CONF_PREFIX/\"".auto/definefi#處理Nginx安裝后,二進制文件、pid、lock等其他文件的路徑可參見configure參數(shù)中路徑類選項的說明have=NGX_SBIN_PATHvalue="\"$NGX_SBIN_PATH\"".auto/definehave=NGX_CONF_PATHvalue="\"$NGX_CONF_PATH\"".auto/definehave=NGX_PID_PATHvalue="\"$NGX_PID_PATH\"".auto/definehave=NGX_LOCK_PATHvalue="\"$NGX_LOCK_PATH\"".auto/definehave=NGX_ERROR_LOG_PATHvalue="\"$NGX_ERROR_LOG_PATH\"".auto/definehave=NGX_HTTP_LOG_PATHvalue="\"$NGX_HTTP_LOG_PATH\"".auto/definehave=NGX_HTTP_CLIENT_TEMP_PATHvalue="\"$NGX_HTTP_CLIENT_TEMP_PATH\"".auto/definehave=NGX_HTTP_PROXY_TEMP_PATHvalue="\"$NGX_HTTP_PROXY_TEMP_PATH\"".auto/definehave=NGX_HTTP_FASTCGI_TEMP_PATHvalue="\"$NGX_HTTP_FASTCGI_TEMP_PATH\"".auto/definehave=NGX_HTTP_UWSGI_TEMP_PATHvalue="\"$NGX_HTTP_UWSGI_TEMP_PATH\"".auto/definehave=NGX_HTTP_SCGI_TEMP_PATHvalue="\"$NGX_HTTP_SCGI_TEMP_PATH\"".auto/define#創(chuàng)建編譯時使用的objs/Makefile文件.auto/make#為objs/Makefile加入需要連接的第三方靜態(tài)庫、動態(tài)庫或者目標(biāo)文件.auto/lib/make#為objs/Makefile加入install功能,當(dāng)執(zhí)行makeinstall時將編譯生成的必要文件復(fù)制到安裝路徑,建立必要的目錄.auto/install#在ngx_auto_config.h文件中加入NGX_SUPPRESS_WARN宏、NGX_SMP宏.auto/stubs#在ngx_auto_config.h文件中指定NGX_USER和NGX_GROUP宏,如果執(zhí)行configure時沒有參數(shù)指定,默認兩者皆為nobody(也就是默認以nobody用戶運行進程)have=NGX_USERvalue="\"$NGX_USER\"".auto/definehave=NGX_GROUPvalue="\"$NGX_GROUP\"".auto/define#顯示configure執(zhí)行的結(jié)果,如果失敗,則給出原因.auto/summary(注:在configure腳本里檢查某個特性是否存在時,會生成一個最簡單的只包含main函數(shù)的C程序,該程序會包含相應(yīng)的頭文件。然后,通過檢查是否可以編譯通過來確認特性是否支持,并將結(jié)果記錄在objs/autoconf.err文件中。后續(xù)檢查頭文件、檢查特性的腳本都用了類似的方法。)1.5.3configure生成的文件當(dāng)configure執(zhí)行成功時會生成objs目錄,并在該目錄下產(chǎn)生以下目錄和文件:|ngx_auto_headers.h|autoconf.err|ngx_auto_config.h|ngx_modules.c|src||core||event|||modules||os|||unix|||win32||http|||modules||||perl||mail||misc|Makefile上述目錄和文件介紹如下。1)src目錄用于存放編譯時產(chǎn)生的目標(biāo)文件。2)Makefile文件用于編譯Nginx工程以及在加入install參數(shù)后安裝Nginx。3)autoconf.err保存configure執(zhí)行過程中產(chǎn)生的結(jié)果。4)ngx_auto_headers.h和ngx_auto_config.h保存了一些宏,這兩個頭文件會被src/core/ngx_config.h及src/os/unix/ngx_linux_config.h文件(可將“l(fā)inux”替換為其他UNIX操作系統(tǒng))引用。5)ngx_modules.c是一個關(guān)鍵文件,我們需要看看它的內(nèi)部結(jié)構(gòu)。一個默認配置下生成的ngx_modules.c文件內(nèi)容如下:#include#include…ngx_module_t*ngx_modules[]={&ngx_core_module,&ngx_errlog_module,&ngx_conf_module,&ngx_events_module,&ngx_event_core_module,&ngx_epoll_module,&ngx_http_module,&ngx_http_core_module,&ngx_http_log_module,&ngx_http_upstream_module,&ngx_http_static_module,&ngx_http_autoindex_module,&ngx_http_index_module,&ngx_http_auth_basic_module,&ngx_http_access_module,&ngx_http_limit_zone_module,&ngx_http_limit_req_module,&ngx_http_geo_module,&ngx_http_map_module,&ngx_http_split_clients_module,&ngx_http_referer_module,&ngx_http_rewrite_module,&ngx_http_proxy_module,&ngx_http_fastcgi_module,&ngx_http_uwsgi_module,&ngx_http_scgi_module,&ngx_http_memcached_module,&ngx_http_empty_gif_module,&ngx_http_browser_module,&ngx_http_upstream_ip_hash_module,&ngx_http_write_filter_module,&ngx_http_header_filter_module,&ngx_http_chunked_filter_module,&ngx_http_range_header_filter_module,&ngx_http_gzip_filter_module,&ngx_http_postpone_filter_module,&ngx_http_ssi_filter_module,&ngx_http_charset_filter_module,&ngx_http_userid_filter_module,&ngx_http_headers_filter_module,&ngx_http_copy_filter_module,&ngx_http_range_body_filter_module,&ngx_http_not_modified_filter_module,NULL};ngx_modules.c文件就是用來定義ngx_modules數(shù)組的。ngx_modules是非常關(guān)鍵的數(shù)組,它指明了每個模塊在Nginx中的優(yōu)先級,當(dāng)一個請求同時符合多個模塊的處理規(guī)則時,將按照它們在ngx_modules數(shù)組中的順序選擇最靠前的模塊優(yōu)先處理。對于HTTP過濾模塊而言則是相反的,因為HTTP框架在初始化時,會在ngx_modules數(shù)組中將過濾模塊按先后順序向過濾鏈表中添加,但每次都是添加到鏈表的表頭,因此,對HTTP過濾模塊而言,在ngx_modules數(shù)組中越是靠后的模塊反而會首先處理HTTP響應(yīng)(參見第6章及第11章的11.9節(jié))。因此,ngx_modules中模塊的先后順序非常重要,不正確的順序會導(dǎo)致Nginx無法工作,這是auto/modules腳本執(zhí)行后的結(jié)果。讀者可以體會一下上面的ngx_modules中同一種類型下(第8章會介紹模塊類型,第10章、第11章將介紹的HTTP框架對HTTP模塊的順序是最敏感的)各個模塊的順序以及這種順序帶來的意義??梢钥闯?,在安裝過程中,configure做了大量的幕后工作,我們需要關(guān)注在這個過程中Nginx做了哪些事情。configure除了尋找依賴的軟件外,還針對不同的UNIX操作系統(tǒng)做了許多優(yōu)化工作。這是Nginx跨平臺的一種具體實現(xiàn),也體現(xiàn)了Nginx追求高性能的一貫風(fēng)格。configure除了生成Makefile外,還生成了ngx_modules.c文件,它決定了運行時所有模塊的優(yōu)先級(在編譯過程中而不是編碼過程中)。對于不需要的模塊,既不會加入ngx_modules數(shù)組,也不會編譯進Nginx產(chǎn)品中,這也體現(xiàn)了輕量級的概念。1.6Nginx的命令行控制在Linux中,需要使用命令行來控制Nginx服務(wù)器的啟動與停止、重載配置文件、回滾日志文件、平滑升級等行為。默認情況下,Nginx被安裝在目錄/usr/local/nginx/中,其二進制文件路徑為/usr/local/nginc/sbin/nginx,配置文件路徑為/usr/local/nginx/conf/nginx.conf。當(dāng)然,在configure執(zhí)行時是可以指定把它們安裝在不同目錄的。為了簡單起見,本節(jié)只說明默認安裝情況下的命令行的使用情況,如果讀者安裝的目錄發(fā)生了變化,那么替換一下即可。(1)默認方式啟動直接執(zhí)行Nginx二進制程序。例如:/usr/local/nginx/sbin/nginx這時,會讀取默認路徑下的配置文件:/usr/local/nginx/conf/nginx.conf。實際上,在沒有顯式指定nginx.conf配置文件路徑時,將打開在configure命令執(zhí)行時使用--conf-path=PATH指定的nginx.conf文件(參見1.5.1節(jié))。(2)另行指定配置文件的啟動方式使用-c參數(shù)指定配置文件。例如:/usr/local/nginx/sbin/nginx-c/tmp/nginx.conf這時,會讀取-c參數(shù)后指定的nginx.conf配置文件來啟動Nginx。(3)另行指定安裝目錄的啟動方式使用-p參數(shù)指定Nginx的安裝目錄。例如:/usr/local/nginx/sbin/nginx-p/usr/local/nginx/(4)另行指定全局配置項的啟動方式可以通過-g參數(shù)臨時指定一些全局配置項,以使新的配置項生效。例如:/usr/local/nginx/sbin/nginx-g"pid/var/nginx/test.pid;"上面這行命令意味著會把pid文件寫到/var/nginx/test.pid中。-g參數(shù)的約束條件是指定的配置項不能與默認路徑下的nginx.conf中的配置項相沖突,否則無法啟動。就像上例那樣,類似這樣的配置項:pidlogs/nginx.pid,是不能存在于默認的nginx.conf中的。另一個約束條件是,以-g方式啟動的Nginx服務(wù)執(zhí)行其他命令行時,需要把-g參數(shù)也帶上,否則可能出現(xiàn)配置項不匹配的情形。例如,如果要停止Nginx服務(wù),那么需要執(zhí)行下面代碼:/usr/local/nginx/sbin/nginx-g"pid/var/nginx/test.pid;"-sstop如果不帶上-g"pid/var/nginx/test.pid;",那么找不到pid文件,也會出現(xiàn)無法停止服務(wù)的情況。(5)測試配置信息是否有錯誤在不啟動Nginx的情況下,使用-t參數(shù)僅測試配置文件是否有錯誤。例如:/usr/local/nginx/sbin/nginx-t執(zhí)行結(jié)果中顯示配置是否正確。(6)在測試配置階段不輸出信息測試配置選項時,使用-q參數(shù)可以不把error級別以下的信息輸出到屏幕。例如:/usr/local/nginx/sbin/nginx-t-q(7)顯示版本信息使用-v參數(shù)顯示Nginx的版本信息。例如:/usr/local/nginx/sbin/nginx-v(8)顯示編譯階段的參數(shù)使用-V參數(shù)除了可以顯示Nginx的版本信息外,還可以顯示配置編譯階段的信息,如GCC編譯器的版本、操作系統(tǒng)的版本、執(zhí)行configure時的參數(shù)等。例如:/usr/local/nginx/sbin/nginx-V(9)快速地停止服務(wù)使用-sstop可以強制停止Nginx服務(wù)。-s參數(shù)其實是告訴Nginx程序向正在運行的Nginx服務(wù)發(fā)送信號量,Nginx程序通過nginx.pid文件中得到master進程的進程ID,再向運行中的master進程發(fā)送TERM信號來快速地關(guān)閉Nginx服務(wù)。例如:/usr/local/nginx/sbin/nginx-sstop實際上,如果通過kill命令直接向nginxmaster進程發(fā)送TERM或者INT信號,效果是一樣的。例如,先通過ps命令來查看nginxmaster的進程ID::ahf5wapi001:root>ps-ef|grepnginxroot108001002:27?00:00:00nginx:masterprocess./nginxroot1080110800002:27?00:00:00nginx:workerprocess接下來直接通過kill命令來發(fā)送信號:kill-sSIGTERM10800或者:kill-sSIGINT10800上述兩條命令的效果與執(zhí)行/usr/local/nginx/sbin/nginx-sstop是完全一樣的。(10)“優(yōu)雅”地停止服務(wù)如果希望Nginx服務(wù)可以正常地處理完當(dāng)前所有請求再停止服務(wù),那么可以使用-squit參數(shù)來停止服務(wù)。例如:/usr/local/nginx/sbin/nginx-squit該命令與快速停止Nginx服務(wù)是有區(qū)別的。當(dāng)快速停止服務(wù)時,worker進程與master進程在收到信號后會立刻跳出循環(huán),退出進程。而“優(yōu)雅”地停止服務(wù)時,首先會關(guān)閉監(jiān)聽端口,停止接收新的連接,然后把當(dāng)前正在處理的連接全部處理完,最后再退出進程。與快速停止服務(wù)相似,可以直接發(fā)送QUIT信號給master進程來停止服務(wù),其效果與執(zhí)行-squit命令是一樣的。例如:kill-sSIGQUIT如果希望“優(yōu)雅”地停止某個worker進程,那么可以通過向該進程發(fā)送WINCH信號來停止服務(wù)。例如:kill-sSIGWINCH(11)使運行中的Nginx重讀配置項并生效使用-sreload參數(shù)可以使運行中的Nginx服務(wù)重新加載nginx.conf文件。例如:/usr/local/nginx/sbin/nginx-sreload事實上,Nginx會先檢查新的配置項是否有誤,如果全部正確就以“優(yōu)雅”的方式關(guān)閉,再重新啟動Nginx來實現(xiàn)這個目的。類似的,-s是發(fā)送信號,仍然可以用kill命令發(fā)送HUP信號來達到相同的效果。kill-sSIGHUP(12)日志文件回滾使用-sreopen參數(shù)可以重新打開日志文件,這樣可以先把當(dāng)前日志文件改名或轉(zhuǎn)移到其他目錄中進行備份,再重新打開時就會生成新的日志文件。這個功能使得日志文件不至于過大。例如:/usr/local/nginx/sbin/nginx-sreopen當(dāng)然,這與使用kill命令發(fā)送USR1信號效果相同。kill-sSIGUSR1(13)平滑升級Nginx當(dāng)Nginx服務(wù)升級到新的版本時,必須要將舊的二進制文件Nginx替換掉,通常情況下這是需要重啟服務(wù)的,但Nginx支持不重啟服務(wù)來完成新版本的平滑升級。升級時包括以下步驟:1)通知正在運行的舊版本Nginx準(zhǔn)備升級。通過向master進程發(fā)送USR2信號可達到目的。例如:kill-sSIGUSR2這時,運行中的Nginx會將pid文件重命名,如將/usr/local/nginx/logs/nginx.pid重命名為/usr/local/nginx/logs/nginx.pid.oldbin,這樣新的Nginx才有可能啟動成功。2)啟動新版本的Nginx,可以使用以上介紹過的任意一種啟動方法。這時通過ps命令可以發(fā)現(xiàn)新舊版本的Nginx在同時運行。3)通過kill命令向舊版本的master進程發(fā)送SIGQUIT信號,以“優(yōu)雅”的方式關(guān)閉舊版本的Nginx。隨后將只有新版本的Nginx服務(wù)運行,此時平滑升級完畢。(14)顯示命令行幫助使用-h或者-?參數(shù)會顯示支持的所有命令行參數(shù)。1.7小結(jié)本章介紹了Nginx的特點以及在什么場景下需要使用Nginx,同時介紹了如何獲取Nginx以及如何配置、編譯、安裝運行Nginx。本章還深入介紹了最為復(fù)雜的configure過程,這部分內(nèi)容是學(xué)習(xí)本書第二部分和第三部分的基礎(chǔ)。第2章Nginx的配置Nginx擁有大量官方發(fā)布的模塊和第三方模塊,這些已有的模塊可以幫助我們實現(xiàn)Web服務(wù)器上很多的功能。使用這些模塊時,僅僅需要增加、修改一些配置項即可。因此,本章的目的是熟悉Nginx的配置文件,包括配置文件的語法格式、運行所有Nginx服務(wù)必須具備的基礎(chǔ)配置以及使用HTTP核心模塊配置靜態(tài)Web服務(wù)器的方法,最后還會介紹反向代理服務(wù)器。通過本章的學(xué)習(xí),讀者可以:熟練地配置一個靜態(tài)Web服務(wù)器;對影響Web服務(wù)器性能的各個配置項有深入的理解;對配置語法有全面的了解。通過互聯(lián)網(wǎng)或其他途徑得到任意模塊的配置說明,然后可通過修改nginx.conf文件來使用這些模塊的功能。2.1運行中的Nginx進程間的關(guān)系在正式提供服務(wù)的產(chǎn)品環(huán)境下,部署Nginx時都是使用一個master進程來管理多個worker進程,一般情況下,worker進程的數(shù)量與服務(wù)器上的CPU核心數(shù)相等。每一個worker進程都是繁忙的,它們在真正地提供互聯(lián)網(wǎng)服務(wù),master進程則很“清閑”,只負責(zé)監(jiān)控管理worker進程。worker進程之間通過共享內(nèi)存、原子操作等一些進程間通信機制來實現(xiàn)負載均衡等功能(第9章將會介紹負載均衡機制,第14章將會介紹負載均衡鎖的實現(xiàn))。部署后Nginx進程間的關(guān)系如圖2-1所示。Nginx是支持單進程(master進程)提供服務(wù)的,那么為什么產(chǎn)品環(huán)境下要按照master-worker方式配置同時啟動多個進程呢?這樣做的好處主要有以下兩點:·由于master進程不會對用戶請求提供服務(wù),只用于管理真正提供服務(wù)的worker進程,所以master進程可以是唯一的,它僅專注于自己的純管理工作,為管理員提供命令行服務(wù),包括諸如啟動服務(wù)、停止服務(wù)、重載配置文件、平滑升級程序等。master進程需要擁有較大的權(quán)限,例如,通常會利用root用戶啟動master進程。worker進程的權(quán)限要小于或等于master進程,這樣master進程才可以完全地管理worker進程。當(dāng)任意一個worker進程出現(xiàn)錯誤從而導(dǎo)致coredump時,master進程會立刻啟動新的worker進程繼續(xù)服務(wù)?!ざ鄠€worker進程處理互聯(lián)網(wǎng)請求不但可以提高服務(wù)的健壯性(一個worker進程出錯后,其他worker進程仍然可以正常提供服務(wù)),最重要的是,這樣可以充分利用現(xiàn)在常見的SMP多核架構(gòu),從而實現(xiàn)微觀上真正的多核并發(fā)處理。因此,用一個進程(master進程)來處理互聯(lián)網(wǎng)請求肯定是不合適的。另外,為什么要把worker進程數(shù)量設(shè)置得與CPU核心數(shù)量一致呢?這正是Nginx與Apache服務(wù)器的不同之處。在Apache上每個進程在一個時刻只處理一個請求,因此,如果希望Web服務(wù)器擁有并發(fā)處理的請求數(shù)更多,就要把Apache的進程或線程數(shù)設(shè)置得更多,通常會達到一臺服務(wù)器擁有幾百個工作進程,這樣大量的進程間切換將帶來無謂的系統(tǒng)資源消耗。而Nginx則不然,一個worker進程可以同時處理的請求數(shù)只受限于內(nèi)存大小,而且在架構(gòu)設(shè)計上,不同的worker進程之間處理并發(fā)請求時幾乎沒有同步鎖的限制,worker進程通常不會進入睡眠狀態(tài),因此,當(dāng)Nginx上的進程數(shù)與CPU核心數(shù)相等時(最好每一個worker進程都綁定特定的CPU核心),進程間切換的代價是最小的。圖2-1部署后Nginx進程間的關(guān)系舉例來說,如果產(chǎn)品中的服務(wù)器CPU核心數(shù)為8,那么就需要配置8個worker進程(見圖2-2)。圖2-2worker進程的數(shù)量盡量與CPU核心數(shù)相等如果對路徑部分都使用默認配置,那么Nginx運行目錄為/usr/local/nginx,其目錄結(jié)構(gòu)如下。|sbin||nginx|conf||koi-win||koi-utf||win-utf||mime.types||mime.types.default||fastcgi_params||fastcgi_params.default||fastcgi.conf||fastcgi.conf.default||uwsgi_params||uwsgi_params.default||scgi_params||scgi_params.default||nginx.conf||nginx.conf.default|logs||error.log||access.log||nginx.pid|html||50x.html||index.html|client_body_temp|proxy_temp|fastcgi_temp|uwsgi_temp|scgi_temp2.2Nginx配置的通用語法Nginx的配置文件其實是一個普通的文本文件。下面來看一個簡單的例子。usernobody;worker_processes8;error_log/var/log/nginx/error.logerror;#pidlogs/nginx.pid;events{useepoll;worker_connections50000;}http{includemime.types;default_typeapplication/octet-stream;log_formatmain'$remote_addr[$time_local]"$request"''$status$bytes_sent"$http_referer"''"$http_user_agent""$http_x_forwarded_for"';access_loglogs/access.logmainbuffer=32k;…}在這段簡短的配置代碼中,每一行配置項的語法格式都將在2.2.2節(jié)介紹,出現(xiàn)的events和http塊配置項將在2.2.1節(jié)介紹,以#符號開頭的注釋將在2.2.3節(jié)介紹,類似“buffer=32k”這樣的配置項的單位將在2.2.4節(jié)介紹。2.2.1塊配置項塊配置項由一個塊配置項名和一對大括號組成。具體示例如下:events{…}http{upstreambackend{server:8080;}gzipon;server{…location/webstatic{gzipoff;}}}上面代碼段中的events、http、server、location、upstream等都是塊配置項,塊配置項之后是否如“l(fā)ocation/webstatic{...}”那樣在后面加上參數(shù),取決于解析這個塊配置項的模塊,不能一概而論,但塊配置項一定會用大括號把一系列所屬的配置項全包含進來,表示大括號內(nèi)的配置項同時生效。所有的事件類配置都要在events塊中,http、server等配置也遵循這個規(guī)定。塊配置項可以嵌套。內(nèi)層塊直接繼承外層塊,例如,上例中,server塊里的任意配置都是基于http塊里的已有配置的。當(dāng)內(nèi)外層塊中的配置發(fā)生沖突時,究竟是以內(nèi)層塊還是外層塊的配置為準(zhǔn),取決于解析這個配置項的模塊,第4章將會介紹http塊內(nèi)配置項沖突的處理方法。例如,上例在http模塊中已經(jīng)打開了“gzipon;”,但其下的location/webstatic又把gzip關(guān)閉了:gzipoff;,最終,在/webstatic的處理模塊中,gzip模塊是按照gzipoff來處理請求的。2.2.2配置項的語法格式從上文的示例可以看出,最基本的配置項語法格式如下:配置項名配置項值1配置項值2…;下面解釋一下配置項的構(gòu)成部分。首先,在行首的是配置項名,這些配置項名必須是Nginx的某一個模塊想要處理的,否則Nginx會認為配置文件出現(xiàn)了非法的配置項名。配置項名輸入結(jié)束后,將以空格作為分隔符。其次是配置項值,它可以是數(shù)字或字符串(當(dāng)然也包括正則表達式)。針對一個配置項,既可以只有一個值,也可以包含多個值,配置項值之間仍然由空格符來分隔。當(dāng)然,一個配置項對應(yīng)的值究竟有多少個,取決于解析這個配置項的模塊。我們必須根據(jù)某個Nginx模塊對一個配置項的約定來更改配置項,第4章將會介紹模塊是如何約定一個配置項的格式。最后,每行配置的結(jié)尾需要加上分號。注意如果配置項值中包括語法符號,比如空格符,那么需要使用單引號或雙引號括住配置項值,否則Nginx會報語法錯誤。例如:log_formatmain'$remote_addr-$remote_user[$time_local]"$request"';2.2.3配置項的注釋如果有一個配置項暫時需要注釋掉,那么可以加“#”注釋掉這一行配置。例如:#pidlogs/nginx.pid;2.2.4配置項的單位大部分模塊遵循一些通用的規(guī)定,如指定空間大小時不用每次都定義到字節(jié)、指定時間時不用精確到毫
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 戰(zhàn)略合作協(xié)議合同模板
- 云數(shù)據(jù)中心架構(gòu)研究-洞察分析
- 藥物生產(chǎn)過程優(yōu)化-洞察分析
- 2023年-2024年項目管理人員安全培訓(xùn)考試題及參考答案【典型題】
- 2023年員工三級安全培訓(xùn)考試題附完整答案【各地真題】
- 2024年企業(yè)主要負責(zé)人安全教育培訓(xùn)試題及參考答案【考試直接用】
- 2023年-2024年新員工入職前安全教育培訓(xùn)試題及完整答案
- 儀器運輸供貨計劃
- 2025年中學(xué)語文教研組工作計劃范文
- 安全與文明施工措施
- 化工原理期末考試練習(xí)題及答案
- 數(shù)值分析課后習(xí)題答案(共81頁)
- 200立方矩形鋼筋混凝土清水池標(biāo)準(zhǔn)圖集(共7頁)
- 網(wǎng)絡(luò)安全運維培訓(xùn)測試題
- 民政部主管社團管理辦法
- 工地施工臨時用水及計算
- 三年級數(shù)學(xué)寒假每日一練
- 工作計劃酒店上半年工作總結(jié)及下半年工作計劃
- 石油詞匯大全-俄語專業(yè)詞匯
- 淺談燃機電廠燃氣管道的完整性管理
- 東營市學(xué)校安全工作先進個人申報表岳向明
評論
0/150
提交評論