Nginx完全開發指南:使用C、C++、JavaScript和Lua ( 簡體 字) |
作者:羅劍鋒 | 類別:1. -> 程式設計 -> 網路編程 -> Nginx 2. -> 程式設計 -> C -> C 3. -> 程式設計 -> C++ -> C++ 4. -> 程式設計 -> 網路編程 -> Javascript |
譯者: |
出版社:電子工業出版社 | 3dWoo書號: 51306 詢問書籍請說出此書號!【缺書】 NT售價: 545 元 |
出版日:6/1/2019 |
頁數:608 |
光碟數:0 |
|
站長推薦: |
印刷:黑白印刷 | 語系: ( 簡體 版 ) |
|
加入購物車 │加到我的最愛 (請先登入會員) |
ISBN:9787121364365 |
作者序 | 譯者序 | 前言 | 內容簡介 | 目錄 | 序 |
(簡體書上所述之下載連結耗時費功, 恕不適用在台灣, 若讀者需要請自行嘗試, 恕不保證) |
作者序: |
譯者序: |
前言:緣起 最早接觸Nginx大概是在2011年,面對著一個全新的Web服務器,和大多數人一樣最初我也是一片茫然,能找到的參考資料十分有限,安裝、配置、運行幾乎都是“摸著石頭過河”,犯過許多低級錯誤。 隨著對Nginx逐漸熟悉,它的高并發處理能力給我留下了深刻的印象,作為一個開源軟件的愛好者,很自然地想要探究一下它的內部工作原理。我由此開始了對Nginx源碼的鉆研之路,中間經過了很多的艱辛曲折,走過了不少的彎路。 我最常用的工作語言是C++,所以在閱讀Nginx源碼時也總以C++的面向對象方式來思考和理解,以對象作為切入點記筆記、畫UML:從最簡單的ngx_str_t、ngx_array_t入手,然后到ngx_request_t、ngx_upstream_t等復雜的結構,再圍繞著這些對象研究相關的功能函數和處理流程,梳理代碼邏輯的同時也摸索著使用C++編寫Nginx模塊的方法,逐漸積累了一些用起來頗為順手的小工具——當然還是比較初級的形式。 五年多前,我被調到了新的工作崗位,需要重度使用Nginx開發,這讓我以前的零散積累終于有了用武之地。那段時間里使用C/C++陸續做了很多東西,也借著機會重新優化了原有的工具代碼。 繁忙的工作之余,我有了種進一步整理經驗的迫切感,因為只有系統完整地分享這些知識,才能讓更多的人基于Nginx二次開發,讓Nginx更好地為網絡世界服務。 同一時間,市面上也出現了一些Nginx開發相關的資料、書籍,但在我看來卻有“粗制濫造”之嫌:行文混亂,“車?轆話”“口頭禪”滿天飛,甚至大段照抄指令說明,還有對源碼的曲解,未免有點兒“誤人子弟”,讀起來實在是難受。終于,在“忍無可忍”的心態之下,我動起了寫作本書的念頭。 經過近一年的努力,現在這本書終于呈現在了讀者面前,結構上基本反映了我學習研究Nginx時的心路歷程,從最初的“一無所知”起步,逐漸深入到定制開發的層次,希望能與讀者“心有戚戚焉”。 Nginx隨感 毫無疑問,Nginx是目前這個星球上所能獲得的最強勁的Web服務器(沒有之一),同時也是目前最成熟、最優秀的TCP/HTTP服務器開發框架。 Nginx資源消耗低,并發處理性能高,配置靈活,能夠連接CGI、PHP、MySQL、Memcached等多種后端,還有著出色的負載均衡能力,可以整合封裝各種service,構建穩定高效的服務。如今Nginx已經成為了網站架構里不可或缺的關鍵組件,廣泛應用于國內外許多大型IT企業內部。每一個繁忙的網站背后,可能都有Nginx默默工作的身影。 在Nginx出現之前,使用C/C++開發Web服務器是項比較“痛苦”的工作,雖然有很多網絡程序庫可以使用(例如asio、libevent、thrift等),但它們通常只關注較底層的基礎功能實現,離成熟的“框架”相距甚遠,不僅開發過程煩瑣低效,而且程序員還必須要處理配置管理、進程間通信、協議解析等許多Web服務之外的其他事情,才能開發出一個較為完善的服務器程序。但即使開發出了這樣的服務器,通常性能上也很難得到保證,會受到程序庫和開發者水平等因素的限制——很長一段時間里,C/C++在Web服務器領域都沒有大展拳腳的機會。 Nginx的橫空出世為Web服務器開辟了一個嶄新的天地,它搭建了一個高性能的服務器開發框架,而且是一個完整的、全功能的服務器。模塊化的架構設計很好地分離了底層支撐模塊和上層邏輯模塊,底層模塊處理了配置、并發等服務器的外圍功能,核心支撐模塊定義了主體的TCP/HTTP處理框架。開發者可以把大部分精力集中在上層的業務功能實現上,再也不必去為其他雜事而分心,提高了軟件的開發效率。 在Nginx框架里C/C++程序員可以盡情發揮自己的專長,充分利用Nginx無阻塞處理的優勢,打造出高質量的Web應用服務器,與其他系統一較高下。 Nginx和C/C++ Igor Sysoev選擇用C語言(準確地說是ANSI C)來實現Nginx肯定是經過了認真的考慮。 作為與UNIX一同誕生的編程語言,C語言一直是系統級編程的首選。和其他高級語言相比,它簡單可靠,更接近計算機底層硬件,運行效率更高。指針更是C語言的一大特色,善用指針能夠完成許多其他語言無法完成的工作。 以C語言實現的Nginx沒有“虛擬機”的成本,省略了不必要的中間環節,直接操縱計算機硬件,從根本上提高了Web服務器的處理能力。雖然C語言不直接支持面向對象,但Nginx靈活運用了指針,采用“結構體+函數指針”的形式,達到了同樣的效果,從而使軟件擁有了良好的結構。 C++是僅次于C的系統級編程語言,在兼容C的同時又增加了異常、模板等新特性,還支持面向對象、泛型、函數式、模板元等多種編程范式,可以說是計算機語言里的一個“龐然大物”。C++的特性很多,有的也很好用,但總體上的確比較復雜,易學難精,容易被誤用和濫用,導致低效、難維護的代碼,我想這可能是Igor Sysoev放棄使用C++的一個重要原因。 另一個可能的原因是C語言本身已經非常穩定,幾十年來沒有太大的變動,在各個系統里都支持得非常好。而C++在1998年才有了第一個標準,而且現在還在發展之中,語言特性還不夠穩定(例如export、register等曾經的關鍵字在C++11里就已經被廢棄),許多編譯器對C++的支持程度也有差異,這與Nginx的高可移植性目標明顯不符。 但C++畢竟還是有很多的優點,類可以更好地封裝信息、異常簡化了錯誤處理、模板能夠在編譯期執行類型計算。在C++11標準頒布之后C++更是幾乎變成了一門“全新”的語言,auto/decltype/nullptr/noexcept等新關鍵字增強了語言的描述能力,標準庫也擴充了相當多的組件,易用性和穩定性都大大提升。 在Nginx里使用C++時要對C++的長處和不足有清醒的認識,避免多層次繼承、虛函數等影響效率的編程范式,只使用經過充分驗證的、能夠切實提高開發效率和性能的語言特性和庫,避免華而不實的技術炫耀,盡量做到像Nginx源碼那樣質樸踏實。只有這樣,才能夠發揮出“1+1>2”的作用,讓Nginx從C++中得到更進一步的發展動力。 Nginx和OpenResty 多年以前Nginx開發使用的語言只能是C和C++,而現在,越來越多的開發者開始轉向了OpenResty,使用Lua搭建高并發、高性能、高擴展性的Web Server。 我接觸OpenResty的時間并不算很長,大約在五年左右。由于C/C++程序員“天生的傲慢”,一開始對OpenResty確實有點兒“抵觸情緒”,總覺得腳本程序比不上C/C++實現。然而隨著使用的增多,特別是在研究了它的源碼之后,我不得不感慨OpenResty的精致、完美和強大,簡直是所有Nginx開發者“夢寐以求的至寶”。 由于agentzh對Nginx的運行機制了如指掌,OpenResty的核心部分——ngx_lua一個模塊就涵蓋了access/rewrite/content/log等多個處理階段,再搭配上小巧靈活的Lua和高效的LuaJIT,我們就能夠在更高級的業務層次上使用“膠水”代碼來調用組合Nginx底層功能,輕松開發出豐富Web服務,極大地節約了寶貴的時間和精力。 當然,OpenResty并不只有ngx_lua,圍繞著ngx_lua還有眾多的庫和輔助工具,構成了一個相當完善的生態環境,這些組件相互支撐,利用得當可以更好地提高生產效率。 OpenResty現在正處于蓬勃發展的階段,今后的OpenResty也許不僅限于Nginx和Web Server,而將成為一個更通用的開發平臺,工作語言也不僅限于Lua,可能還會有其他新的語言(例如agentzh正在做的edgelang和fanlang),讓我們拭目以待。 “大事件” 2019年,Nginx身上發生了一件了不得的“大事件”:在獨立運營了8年之后,Nginx.Inc公司正式被它的“競爭對手”F5 Networks收購。 收購的價格并不算高,只有6.7億美元。可以比較一下去年被微軟收購的源碼托管網站GitHub,出價是75億。對于Nginx這個幾乎占據了互聯網一半份額的頂尖Web服務器來說,感覺實在是有點低。 這也算得上是開源軟件商業化的又一個標志性案例了。再往前,還有IBM以340億美元收購RedHat、Sun以10億美元收購MySQL(但后來又被Oracle收購)。昔日的一個個免費開源明星軟件,懷著使命和愿景陸續走向商業化,但又在這條道路上最終倒下。理想終究敗給了現實,令人不得不感慨這個“美麗而又殘酷”的世界。[ 出自《進擊的巨人 Season 1》片尾曲“美??殘酷?世界”。] 目前“碩果僅存”的同級知名開源軟件應該只有Apache和Linux了。值得注意的是它們并沒有成立商業公司,而是以基金會的形式運作,通過贊助和會員制等形式來籌措資金。另一方面也確實是因為它們的“體量”足夠大,能夠把“免費”“開源”的大旗繼續打下去。 當然,Nginx和F5都發表了官方聲明,表示Nginx會繼續保持開源,共同維護開源社區的活力。在這一點上我選擇相信他們,相信被收購后的Nginx會有更加光明的未來。 再補上一句私心話:“還等著在Nginx上跑HTTP/3呢。” 新版的變化 我一直是C++語言的堅定擁護者,很早就在積極推動使用C++開發定制Nginx,但這幾年下來感覺“收效甚微”:一是C語言開發的慣性太大,二是操作系統對C++標準支持不力,無法用上11/14的特性。幾番折騰下來,有點“心灰意冷”了。 所以這次的新版就改以C作為主力開發語言,同時“忍痛割愛”,大幅度刪減了各章節的C++代碼,C++的全部內容都壓縮到一個章節里(第20章),不再詳細介紹C++封裝類的具體實現和內部工作原理,也許這樣會更貼近目前Nginx開發的現狀。 上一版編寫時比較匆忙,有些重要知識沒來得及講,這次“清退”C++后騰出了大量的頁碼,就新增了兩章(第12、14章),仔細分析Nginx的內存池和進程間通信機制,補上了“短板”,可以說離“完全”又近了一步。 此外還有一些其他的改動,比如重新梳理子請求的內部實現(第11章),JavaScript由附錄升級為正文(第21章),專門用兩章(第23、24章)論述調試、測試與性能優化(非常有用的火焰圖)等。 簡而言之,“本店全面翻新升級,歡迎光臨”。 學習HTTP Nginx是一個Web服務器,主要用的是HTTP協議,但在實際工作中我經常看到很多人對HTTP了解有限,知識掌握的不全面,學習Nginx開發時難免“磕磕絆絆”,不明白Nginx為什么要這么做、那么做,即使有源碼也是不明就里。 所以我打算近期在極客時間(https://time.geekbang.org)開設一個專欄課程,名字還沒想好,暫且叫“透視HTTP協議”,以RFC為準,精讀透講HTTP還有HTTPS。讀者如果感興趣可以去網站上看看,肯定不會讓你失望的。 這也是我第一次自己給自己打廣告,但愿不會影響你的心情。 致謝 首先當然要感謝Nginx的作者Igor Sysoev,沒有他就不會有如此優秀的Web服務器,也就不會有本書的誕生。 OpenResty創始人章亦春(agentzh)是一位非常親切隨和的人,在Nginx、DSL、Dynamic Tracing等領域造詣極高,本書部分章節有幸經他審閱,在此表示最誠摯的謝意。 親情永遠是人生命中最值得珍惜的部分,我要感謝父母多年來的養育之恩和“后勤”工作,感謝妻子在生活中的陪伴,感謝兩個可愛的女兒,愿你們能夠永遠幸福快樂。 最后,我也要感謝讀者選擇本書,希望讀者能夠在閱讀過程中有所收獲,在Nginx開發過程中獲得樂趣。 那么,祝您閱讀愉快!
您的朋友 羅劍鋒 2019年5月19日 于 北京 798園區 |
內容簡介:Nginx是著名的Web服務器,性能優異,運行效率遠超傳統的Apache、Tomcat,廣泛應用于國內外諸多頂級互聯網公司。Nginx的一個突出特點是其靈活優秀的模塊化架構,可以在不修改核心的前提下增加任意功能,自2004年發布至今,已經擁有百余個官方及非官方的功能模塊(如proxy、mysql、redis、rtmp、lua等),使得Nginx成長為了一個近乎“全能”的服務器軟件。Nginx功能強大,架構復雜,學習、維護和開發的門檻較高。為了幫助讀者跨越這一障礙,本書深入最新的Nginx源碼(Stable 1.16.0),詳細剖析了模塊體系、動態插件、功能框架、內存分配、進程模型、事件驅動、線程池、TCP/UDP/HTTP處理等Nginx核心運行機制,在此基礎上講解如何使用C、C++、JavaScript、Lua等語言來增強擴展Nginx,讓任何人都能夠便捷、輕松地開發和定制Nginx,進而應用到自己的實際工作中,創造出更多的價值。本書結構嚴謹、脈絡清晰、論述精確、詳略得當、圖文并茂,值得廣大軟件開發工程師、系統運維工程師和編程愛好者擁有。 |
目錄:第0章 導讀 1 0.1 于本書 1 0.2 讀者對象 3 0.3 讀者要求 4 0.4 運行環境 5 0.5 本書的結構 5 0.6 如何閱讀本書 6 0.7 本書的源碼 7 第1章 Nginx入門 8 1.1 關于Nginx 8 1.1.1 歷史 9 1.1.2 特點 9 1.1.3 進程模型 10 1.1.4 版本 12 1.2 安裝Nginx 12 1.2.1 準備工作 13 1.2.2 快速安裝 13 1.2.3 運行命令 14 1.2.4 驗證安裝 15 1.2.5 定制安裝 16 1.3 配置Nginx 18 1.3.1 語法格式 19 1.3.2 進程管理 20 1.3.3 動態模塊 22 1.3.4 運行日志 22 1.3.5 事件機制 22 1.4 HTTP服務 23 1.4.1 基本配置 24 1.4.3 location配置 25 1.4.4 file配置 26 1.5 TCP/UDP服務 27 1.6 反向代理 28 1.6.1 上游集群 28 1.6.2 負載均衡 29 1.6.3 代理轉發 30 1.7 變量 30 1.8 總結 32 第2章 Nginx開發準備 33 2.1 源碼結構 33 2.2 源碼特點 34 2.2.1 代碼風格 34 2.2.2 代碼優化 35 2.2.3 面向對象思想 35 2.3 頭文件 36 2.4 總結 36 第3章 Nginx基礎設施 37 3.1 常數 37 3.1.1 環境信息 37 3.1.2 版本信息 38 3.1.3 錯誤碼 38 3.2 整數類型 39 3.2.1 標準整數類型 39 3.2.2 自用整數類型 40 3.2.3 無效值 40 3.3 內存池 42 3.3.1 結構定義 42 3.3.2 操作函數 43 3.3.3 用法示例 44 3.4 字符串 44 3.4.1 結構定義 44 3.4.2 操作函數 45 3.4.3 用法示例 48 3.5 時間 49 3.5.1 結構定義 49 3.5.2 操作函數 49 3.5.3 用法示例 50 3.6 日期 50 3.6.1 結構定義 50 3.6.2 操作函數 51 3.6.3 用法示例 52 3.7 運行日志 52 3.7.1 結構定義 52 3.7.2 操作函數 53 3.7.3 用法示例 54 3.8 摘要算法 54 3.8.1 Times33 55 3.8.2 CRC 55 3.8.3 MurmurHash 56 3.8.4 MD5 57 3.8.5 SHA-1 57 3.9 數據編碼 58 3.9.1 Base64 58 3.9.2 HTML/JSON 59 3.10 總結 60 第4章 Nginx高級數據結構 61 4.1 動態數組 61 4.1.1 結構定義 62 4.1.2 操作函數 63 4.1.3 用法示例 64 4.2 單向鏈表 65 4.2.1 結構定義 65 4.2.2 操作函數 66 4.2.3 用法示例 66 4.3 雙端隊列 68 4.3.1 結構定義 68 4.3.2 操作函數 69 4.3.3 用法示例 71 4.4 紅黑樹 72 4.4.1 結構定義 73 4.4.2 操作函數 75 4.4.3 用法示例 76 4.5 緩沖區 78 4.5.1 結構定義 78 4.5.2 操作函數 80 4.5.3 用法示例 81 4.6 數據塊鏈 82 4.6.1 結構定義 82 4.6.2 操作函數 83 4.6.3 用法示例 83 4.7 總結 84 第5章 Nginx開發概述 85 5.1 開發示例 85 5.1.1 模塊設計 85 5.1.2 配置解析 86 5.1.3 處理函數 88 5.1.4 模塊集成 90 5.1.5 編譯腳本 91 5.1.6 測試驗證 92 5.2 開發流程 92 5.2.1 設計 93 5.2.2 開發 93 5.2.3 編譯 94 5.2.4 測試驗證 94 5.2.5 調優 94 5.2.6 流程圖 95 5.3 編譯腳本 95 5.3.1 運行機制 96 5.3.2 腳本變量 96 5.3.3 添加模塊 97 5.3.4 腳本格式 97 5.3.5 舊式腳本 98 5.4 總結 99 第6章 Nginx模塊體系 100 6.1 模塊架構 100 6.1.1 結構定義 100 6.1.2 模塊的簽名 102 6.1.3 模塊的種類 103 6.1.4 模塊的函數指針表 104 6.1.5 模塊的類圖 105 6.1.6 模塊的組織形式 106 6.1.7 模塊的靜態加載 108 6.1.8 模塊的動態加載 110 6.2 配置解析 113 6.2.1 結構定義 113 6.2.2 基本流程 116 6.2.3 存儲模型 118 6.2.4 訪問配置數據 122 6.2.5 配置數據的位置 123 6.2.6 配置數據的解析 124 6.2.7 配置數據的合并 126 6.2.8 配置指令的類型 127 6.3 源碼分析 128 6.3.1 ngx_core_module 128 6.3.2 ngx_errlog_module 130 6.4 總結 132 第7章 Nginx功能框架 134 7.1 框架簡介 134 7.1.1 模塊分類 134 7.1.2 處理流程 135 7.1.3 請求的處理階段 137 7.1.4 請求結構體 138 7.1.5 請求的環境數據 140 7.2 處理引擎 141 7.2.1 函數原型 141 7.2.2 處理函數的存儲方式 141 7.2.3 內容處理函數 142 7.2.4 引擎的數據結構 143 7.2.5 引擎的初始化 144 7.2.6 引擎的運行機制 145 7.2.7 日志階段的處理 148 7.3 過濾引擎 148 7.3.1 函數原型 148 7.3.2 過濾函數鏈表 149 7.3.3 過濾函數的順序 150 7.3.4 過濾鏈表的運行機制 152 7.3.5 請求體過濾 153 7.4 源碼分析 153 7.4.1 ngx_http_static_module 154 7.4.2 ngx_http_not_modified_filter_module 155 7.5 總結 156 第8章 Nginx請求處理 158 8.1 狀態碼 158 8.2 請求結構體 159 8.3 請求行 160 8.3.1 請求方法 160 8.3.2 協議版本號 161 8.3.3 資源標識符 161 8.4 請求頭 162 8.5 請求體 163 8.5.1 結構定義 163 8.5.2 操作函數 164 8.6 響應頭 164 8.6.1 結構定義 164 8.6.2 操作函數 165 8.7 響應體 166 8.8 源碼分析 166 8.8.1 ngx_http_static_module 166 8.8.2 ngx_http_not_modified_filter_module 168 8.9 開發示例:content handler 169 8.9.1 模塊設計 169 8.9.2 配置數據 169 8.9.3 處理函數 170 8.9.4 注冊函數 171 8.9.5 模塊集成 172 8.9.6 編譯腳本 173 8.9.7 測試驗證 173 8.10 開發示例:filter 173 8.10.1 模塊設計 173 8.10.2 配置數據 174 8.10.3 環境數據 174 8.10.4 注冊過濾函數 175 8.10.5 過濾響應頭 175 8.10.6 過濾響應體 176 8.10.7 模塊集成 178 8.10.8 編譯腳本 179 8.10.9 測試驗證 179 8.11 總結 180 第9章 Nginx請求轉發 181 9.1 框架簡介 181 9.1.1 工作原理 182 9.1.2 請求結構體 183 9.1.3 上游結構體 184 9.1.4 上游配置參數 185 9.2 請求轉發 186 9.2.1 回調函數 186 9.2.2 初始化 188 9.2.3 設置參數 189 9.2.4 啟動連接 190 9.2.5 處理響應頭 190 9.2.6 處理響應體 191 9.3 負載均衡 192 9.3.1 結構定義 192 9.3.2 初始化模塊入口 196 9.3.3 初始化地址列表 197 9.3.4 初始化算法 199 9.3.5 執行算法 200 9.4 源碼分析 200 9.4.1 ngx_http_memcached_module 201 9.4.2 ngx_http_upstream_ip_hash_module 203 9.5 開發示例:upstream 206 9.5.1 模塊設計 206 9.5.2 配置數據 206 9.5.3 上行數據 208 9.5.4 下行數據 208 9.5.5 啟動轉發 209 9.5.6 注冊函數 210 9.5.7 模塊集成 210 9.5.8 編譯腳本 211 9.5.9 測試驗證 212 9.6 開發示例:balance 212 9.6.1 模塊設計 212 9.6.2 配置數據 212 9.6.3 算法數據結構 213 9.6.4 模塊入口 213 9.6.5 算法實現 214 9.6.6 模塊集成 215 9.6.7 編譯腳本 216 9.6.8 測試驗證 216 9.7 總結 216 第10章 Nginx子請求 218 10.1 框架簡介 218 10.1.1 工作原理 219 10.1.2 請求結構體 220 10.1.3 回調函數 221 10.1.4 待處理請求鏈表 223 10.1.5 子請求存儲結構 223 10.2 運行機制 223 10.2.1 創建子請求 224 10.2.2 處理引擎 228 10.2.3 數據整理 229 10.3 開發示例 230 10.3.1 模塊設計 231 10.3.2 配置數據 231 10.3.3 環境數據 231 10.3.4 回調函數 231 10.3.5 處理函數 232 10.3.6 注冊函數 233 10.3.7 測試驗證 234 10.4 總結 234 第11章 Nginx變量 236 11.1 結構定義 236 11.1.1 變量 237 11.1.2 復雜變量 238 11.1.3 變量的存儲 239 11.1.4 請求結構體 239 11.2 操作變量 240 11.2.1 添加變量 240 11.2.2 獲取變量 241 11.2.3 修改變量 242 11.2.4 編譯復雜變量 242 11.2.5 獲取復雜變量 242 11.3 開發示例:變量 243 11.3.1 模塊設計 243 11.3.2 定義變量 243 11.3.3 添加變量 244 11.3.4 獲取變量 244 11.3.5 測試驗證 245 11.4 開發示例:復雜變量 246 11.4.1 模塊設計 246 11.4.2 定義復雜變量 246 11.4.3 編譯復雜變量 246 11.4.4 獲取復雜變量 247 11.4.5 測試驗證 247 11.5 總結 247 第12章 Nginx內存管理機制 249 12.1 基本系統調用 250 12.1.1 malloc 250 12.1.2 posix_memalign 251 12.1.3 free 251 12.2 塊式內存池 252 12.2.1 結構定義 252 12.2.2 常量定義 255 12.2.3 創建內存池 255 12.2.4 分配內存 257 12.2.5 分配大塊內存 258 12.2.6 分配小塊內存 259 12.2.7 釋放內存 264 12.2.8 清理機制 264 12.2.9 清空內存池 265 12.2.10 銷毀內存池 266 12.3 頁式內存池 267 12.3.1 結構定義 268 12.3.2 常量定義 270 12.3.3 初始化內存池 271 12.3.4 分配內存 273 12.3.5 分配大塊內存 275 12.3.6 分配小塊內存 277 12.3.7 釋放內存 280 12.4 總結 282 第13章 Nginx進程機制 284 13.1 基本系統調用 284 13.1.1 errno 284 13.1.2 getrlimit 285 13.2 進程系統調用 285 13.2.1 getpid 285 13.2.2 fork 286 13.2.3 waitpid 286 13.3 信號系統調用 287 13.3.1 kill 287 13.3.2 sigaction 288 13.3.3 sigsuspend 288 13.4 結構定義 288 13.4.1 ngx_cycle_t 288 13.4.2 ngx_core_conf_t 289 13.4.3 ngx_process_t 290 13.5 全局變量 291 13.5.1 命令行相關 291 13.5.2 操作系統相關 292 13.5.3 進程功能相關 292 13.5.4 信號功能相關 293 13.6 啟動過程 293 13.6.1 基本流程 293 13.6.2 解析命令行 294 13.6.3 版本和幫助信息 294 13.6.4 初始化cycle 294 13.6.5 測試配置 296 13.6.6 發送信號 297 13.6.7 守護進程化 297 13.6.8 啟動工作進程 298 13.6.9 流程圖 298 13.7 信號處理 299 13.7.1 信號處理函數 300 13.7.2 發送信號 300 13.7.3 處理信號 301 13.8 單進程模式 302 13.8.1 single進程 302 13.8.2 single進程流程圖 304 13.9 多進程模式 304 13.9.1 產生子進程 304 13.9.2 master進程 306 13.9.3 master進程流程圖 309 13.9.4 worker進程 310 13.9.5 worker進程流程圖 312 13.10 總結 313 第14章 Nginx進程間通信機制 315 14.1 基本系統調用 315 14.1.1 atomic 315 14.1.2 sched_yield 316 14.1.3 semaphore 316 14.1.4 mmap 317 14.2 共享內存(Ⅰ) 317 14.2.1 結構定義 317 14.2.2 創建共享內存 317 14.2.3 使用共享內存 318 14.3 自旋鎖 318 14.3.1 自旋鎖定 319 14.3.2 解除鎖定 320 14.3.3 使用自旋鎖 320 14.4 互斥鎖 320 14.4.1 結構定義 320 14.4.2 創建互斥鎖 321 14.4.3 互斥鎖定 322 14.4.4 解除鎖定 323 14.4.5 銷毀互斥鎖 324 14.4.6 使用互斥鎖 324 14.5 讀寫鎖 325 14.5.1 寫鎖定 325 14.5.2 讀鎖定 325 14.5.3 解除鎖定 326 14.5.4 降級鎖定 326 14.5.5 使用讀寫鎖 327 14.6 共享內存(Ⅱ) 327 14.6.1 結構定義 327 14.6.2 添加共享內存 328 14.6.3 創建共享內存 329 14.6.4 使用共享內存 330 14.7 總結 331 第15章 Nginx事件機制 333 15.1 基本系統調用 333 15.1.1 errno 334 15.1.2 ioctl 334 15.1.3 setitimer 334 15.1.4 gettimeofday 334 15.2 socket系統調用 335 15.2.1 socket 335 15.2.2 bind 335 15.2.3 listen 336 15.2.4 accept 336 15.2.5 connect 336 15.2.6 recv 336 15.2.7 send 337 15.2.8 setsockopt 337 15.2.9 close 337 15.2.10 函數關系圖 338 15.3 epoll系統調用 338 15.3.1 epoll_create 339 15.3.2 epoll_ctl 339 15.3.3 epoll_wait 340 15.3.4 LT和ET 341 15.3.5 函數關系圖 342 15.4 結構定義 342 15.4.1 ngx_event_t 342 15.4.2 ngx_connection_t 343 15.4.3 ngx_listening_t 345 15.4.4 ngx_cycle_t 346 15.4.5 ngx_os_io_t 347 15.4.6 ngx_event_actions_t 351 15.4.7 ngx_posted_events 353 15.4.8 關系圖 354 15.5 定時器 354 15.5.1 紅黑樹 354 15.5.2 操作函數 355 15.5.3 超時處理 355 15.6 模塊體系 358 15.6.1 函數指針表 358 15.6.2 模塊的組織形式 359 15.6.3 核心配置 361 15.6.4 epoll模塊 362 15.7 全局變量 363 15.7.1 更新時間相關 363 15.7.2 事件機制相關 364 15.7.3 負載均衡相關 365 15.7.4 統計相關 365 15.8 進程初始化 366 15.8.1 初始化函數 366 15.8.2 基本參數初始化 368 15.8.3 事件機制初始化 369 15.8.4 連接池初始化 370 15.8.5 監聽端口初始化 371 15.8.6 初始化流程圖 373 15.9 運行機制 373 15.9.1 添加事件 374 15.9.2 刪除事件 377 15.9.3 處理事件 378 15.9.4 接受連接 382 15.9.5 負載均衡 384 15.10 避免阻塞 389 15.11 總結 390 第16章 Nginx多線程機制 392 16.1 eventfd系統調用 392 16.2 pthread系統調用 393 16.3 結構定義 393 16.3.1 ngx_thread_task_t 394 16.3.2 ngx_thread_pool_queue_t 394 16.3.3 ngx_thread_pool_t 395 16.3.4 結構關系圖 396 16.4 事件通知 396 16.4.1 函數接口 396 16.4.2 初始化 397 16.4.3 發送通知 398 16.4.4 處理通知 398 16.5 運行機制 399 16.5.1 完成任務隊列 399 16.5.2 創建線程池 399 16.5.3 創建任務 400 16.5.4 投遞任務 401 16.5.5 執行任務 402 16.5.6 任務完成回調 404 16.5.7 銷毀線程池 405 16.6 開發示例 406 16.6.1 模塊設計 406 16.6.2 配置數據 407 16.6.3 線程任務 407 16.6.4 任務完成回調 408 16.6.5 投遞任務 409 16.6.6 測試驗證 410 16.7 總結 410 第17章 Nginx Stream機制 412 17.1 模塊體系 412 17.1.1 函數指針表 413 17.1.2 基礎模塊 413 17.1.3 核心模塊 415 17.1.4 結構關系圖 416 17.1.5 存儲模型 416 17.2 監聽端口 418 17.2.1 結構定義 418 17.2.2 解析配置 420 17.2.3 啟動監聽 424 17.3 處理引擎 425 17.3.1 階段定義 426 17.3.2 函數原型 426 17.3.3 處理函數的存儲方式 426 17.3.4 引擎數據結構 427 17.3.5 結構關系圖 428 17.3.6 引擎的初始化 428 17.4 過濾引擎 430 17.4.1 函數原型 430 17.4.2 過濾函數鏈表 430 17.5 運行機制 431 17.5.1 會話結構體 431 17.5.2 創建會話 432 17.5.3 執行引擎 435 17.5.4 通用階段處理 437 17.5.5 預讀數據 438 17.5.6 產生響應數據 442 17.5.7 過濾數據 442 17.5.8 結束會話 442 17.6 開發示例 443 17.6.1 discard協議 444 17.6.2 time協議 446 17.6.3 echo協議 448 17.7 總結 450 第18章 Nginx HTTP機制 452 18.1 結構定義 452 18.1.1 ngx_http_state_e 452 18.1.2 ngx_http_connection_t 453 18.1.3 ngx_http_request_t 453 18.2 初始化連接 454 18.2.1 建立連接 455 18.2.2 等待數據 456 18.2.3 讀取請求頭 458 18.3 執行引擎 463 18.3.1 初始化引擎 463 18.3.2 通用階段 465 18.3.3 改寫階段 466 18.3.4 訪問控制階段 467 18.3.5 內容產生階段 469 18.4 處理請求體 470 18.4.1 丟棄緩沖區數據 470 18.4.2 讀取并丟棄數據 471 18.4.3 讀事件處理函數 473 18.4.4 啟動丟棄處理 474 18.5 發送數據 475 18.5.1 發送初始化 475 18.5.2 事件處理函數 476
18.6 結束請求 478 18.6.1 釋放請求資源 478 18.6.2 檢查引用計數結束請求 479 18.6.3 檢查狀態結束請求 480 18.6.4 綜合處理結束請求 481 18.7 總結 483 第19章 Nginx與設計模式 485 19.1 設計模式簡介 485 19.2 框架級別的模式 485 19.3 業務級別的模式 487 19.4 代碼級別的模式 488 19.5 總結 490 第20章 Nginx C++開發 491 20.1 語言簡介 491 20.2 開發準備 492 20.2.1 程序庫 492 20.2.2 頭文件 492 20.2.3 編程范式 493 20.2.4 實現原則 493 20.2.5 源碼組織 494 20.2.6 編譯腳本 495 20.3 封裝類 497 20.3.1 基礎設施 497 20.3.2 高級數據結構 500 20.3.3 功能框架 505 20.3.4 請求處理 509 20.4 開發示例:content handler 510 20.4.1 配置信息類 510 20.4.2 業務邏輯類 511 20.4.3 模塊集成類 512 20.4.4 實現源文件 515 20.5 開發示例:filter 515 20.5.1 配置信息類 515 20.5.2 環境數據類 515 20.5.3 業務邏輯類 516 20.5.4 模塊集成類 518 20.5.5 實現源文件 519 20.6 總結 519 第21章 Nginx JavaScript開發 521 21.1 語言簡介 521 21.2 模塊簡介 522 21.3 開發準備 523 21.4 指令簡介 523 21.5 功能接口 524 21.5.1 運行日志 524 21.5.2 變量 525 21.5.3 請求處理 525 21.5.4 子請求 527 21.5.5 定時器 527 21.5.6 流處理 527 21.6 開發示例 528 21.6.1 content handler 528 21.6.2 subrequest 529 21.6.3 A/B testing 530 21.7 總結 531 第22章 Nginx Lua開發 532 22.1 語言簡介 532 22.2 模塊簡介 533 22.2.1 http_lua 533 22.2.2 stream_lua 533 22.2.3 lua-resty-lib 534
22.3 開發準備 534 22.4 指令簡介 535 22.4.1 配置指令 536 22.4.2 功能指令 536 22.4.3 指令關系圖 538 22.5 應用開發流程 538 22.6 功能接口 539 22.6.1 運行日志 539 22.6.2 時間與日期 540 22.6.3 變量 540 22.6.4 正則表達式 541 22.6.5 請求處理 542 22.6.6 請求轉發 544 22.6.7 子請求 545 22.6.8 定時器 546 22.6.9 共享內存 546 22.7 開發示例 547 22.7.1 content handler 548 22.7.2 filter 549 22.7.3 upstream 550 22.7.4 subrequest 550 22.7.5 discard 551 22.7.6 echo 552 22.8 總結 552 第23章 Nginx調試與測試 554 23.1 調試 554 23.1.1 調試器 554 23.1.2 調試斷點 555 23.1.3 調試日志 556 23.2 功能測試 558 23.2.1 測試套件 559
23.2.2 測試用例 559 23.2.3 運行測試 564 23.3 性能測試 564 23.3.1 ab 565 23.3.2 http_load 565 23.3.3 wrk 566 23.3.4 Test::Nginx 567 23.4 總結 568 第24章 Nginx性能分析 569 24.1 簡介 569 24.2 火焰圖 570 24.3 分析工具 572 24.3.1 使用方式 572 24.3.2 處理數據 573 24.4 動態追蹤 576 24.4.1 CPU分析 577 24.4.2 I/O分析 579 24.4.3 Memory分析 580 24.4.4 觀測工具 581 24.5 總結 582 第25章 結束語 583 25.1 本書的遺憾 583 25.2 下一步 583 25.3 臨別贈言 584 附錄A 推薦書目 585 附錄B 字符串格式化 587 附錄C 開發輔助工具 589 |
序: |