Nginx是由俄羅斯工程師IgorSysoev開發的一個高性能Web服務器,運行效率遠超傳統的Apache、Tomcat,是世界第二大Web服務器,被國內外諸多頂級互聯網公司采用。
Nginx的一個突出特點是其靈活優秀的模塊化架構,可以在不修改核心的前提下增加任意功能,自2004年發布至今,已經擁有百余個官方及非官方的功能模塊(如fastcgi、memcached、mysql等),使得Nginx成長為了一個近乎”全能」的服務器軟件。
Nginx以純C語言實現,開發擴展功能模塊也大多使用C語言,但由於C語言固有的過程式特性,編寫、調試代碼都較麻煩——特別是對於Nginx的初學者。
本書深入源碼,詳細解析了模塊體系、配置指令、HTTP框架等Nginx核心運行機制,並在此基礎上講解如何使用C++和Boost程序庫來開發Nginx模塊,充分利用現代C++里的大量新特性和庫組件,讓Nginx的模塊開發變得更加便捷、輕松和愉快。
目錄
第0章 導讀1
0.1 關於本書1
0.2 讀者對象2
0.3 讀者要求3
0.4 運行環境3
0.5 本書的結構4
0.6 如何閱讀本書6
0.7 本書的源碼6
第1章 Nginx入門7
1.1 關於Nginx7
1.1.1 歷史8
1.1.2 特點8
1.1.3 進程模型9
1.1.4 版本10
1.2 安裝Nginx11
1.2.1 准備工作11
1.2.2 快速安裝11
1.2.3 運行命令12
1.2.4 驗證安裝13
1.2.5 定制安裝14
1.3 配置Nginx15
1.3.1 配置文件格式16
1.3.2 進程配置17
1.3.3 運行日志配置18
1.3.4 http配置18
1.3.5 server配置19
1.3.6 location配置20
1.3.7 文件訪問配置21
1.3.8 upstream配置22
1.3.9 變量22
1.4 總結24
第2章 Nginx開發准備25
2.1 開發環境25
2.1.1 C++標准25
2.1.2 Boost程序庫26
2.2 Nginx的目錄結構26
2.3 Nginx源碼的特點27
2.3.1 代碼風格28
2.3.2 代碼優化28
2.3.3 面向對象思想28
2.4 在Nginx里使用C++29
2.4.1 實現原則29
2.4.2 代碼風格29
2.4.3 編譯腳本30
2.5 基本的C++包裝類32
2.5.1 類定義32
2.5.2 構造和析構33
2.5.3 成員函數33
2.6 總結34
第3章 Nginx基礎設施35
3.1 頭文件35
3.2 整數類型36
3.2.1 標准整數類型36
3.2.2 自定義整數類型36
3.2.3 無效值37
3.2.4 C++封裝38
3.3 錯誤處理41
3.3.1 錯誤碼定義41
3.3.2 C++異常41
3.4 內存池44
3.4.1 結構定義44
3.4.2 操作函數45
3.4.3 C++封裝45
3.4.4 清理機制48
3.4.5 C++內存分配器50
3.5 字符串52
3.5.1 結構定義52
3.5.2 操作函數53
3.5.3 C++封裝55
3.6 時間與日期58
3.6.1 時間結構定義58
3.6.2 時間操作函數58
3.6.3 日期結構定義59
3.6.4 日期操作函數60
3.6.5 C++封裝時間61
3.6.6 C++封裝日期62
3.7 運行日志64
3.7.1 結構定義65
3.7.2 操作函數65
3.7.3 C++封裝66
3.8 總結68
第4章 Nginx高級數據結構71
4.1 動態數組71
4.1.1 結構定義71
4.1.2 操作函數73
4.1.3 C++封裝73
4.2 單向鏈表76
4.2.1 結構定義77
4.2.2 操作函數78
4.2.3 C++迭代器79
4.2.4 C++封裝鏈表81
4.3 雙端隊列84
4.3.1 結構定義84
4.3.2 操作函數85
4.3.3 C++節點87
4.3.4 C++迭代器89
4.3.5 C++封裝隊列90
4.4 緩沖區95
4.4.1 結構定義95
4.4.2 操作函數97
4.4.3 C++封裝98
4.5 數據塊鏈100
4.5.1 結構定義100
4.5.2 操作函數101
4.5.3 C++節點101
4.5.4 C++迭代器103
4.5.5 C++封裝數據塊鏈105
4.6 鍵值對107
4.6.1 簡單鍵值對107
4.6.2 散列表鍵值對107
4.7 總結108
第5章 Nginx開發綜述111
5.1 最簡單的Nginx模塊111
5.1.1 模塊設計112
5.1.2 配置解析112
5.1.3 處理函數114
5.1.4 模塊集成116
5.1.5 編譯腳本和命令117
5.1.6 測試驗證118
5.2 Nginx開發基本流程119
5.2.1 設計119
5.2.2 開發119
5.2.3 編譯120
5.2.4 測試驗證120
5.2.5 調優121
5.3 Nginx的模塊121
5.3.1 模塊的數據結構121
5.3.2 模塊的種類123
5.3.3 http模塊124
5.3.4 模塊的類圖124
5.3.5 模塊的組織形式125
5.4 Nginx的配置127
5.4.1 結構定義128
5.4.2 配置解析的基本流程131
5.4.3 配置數據的存儲模型133
5.4.4 訪問配置數據138
5.4.5 確定配置數據的位置138
5.4.6 配置解析函數140
5.4.7 配置數據的合並141
5.4.8 配置指令的類型142
5.5 Nginx模塊源碼分析143
5.5.1 ngx_core_module143
5.5.2 ngx_errlog_module146
5.6 Nginx的編譯腳本147
5.6.1 運行機制147
5.6.2 使用的變量148
5.7 C++封裝模塊信息149
5.7.1 NgxModuleConfig149
5.7.2 NgxModule153
5.8 C++封裝配置解析155
5.8.1 NgxCommand155
5.8.2 NgxTake155
5.8.3 NGX_MODULE_NULL157
5.9 C++開發Nginx模塊158
5.9.1 C++模塊的基本組成158
5.9.2 配置信息類159
5.9.3 業務邏輯類160
5.9.4 模塊集成類162
5.9.5 實現源文件164
5.9.6 增加更多功能164
5.10 總結165
第6章 Nginx HTTP框架綜述169
6.1 HTTP框架簡介169
6.1.1 模塊分類169
6.1.2 處理流程170
6.1.3 請求結構體172
6.1.4 請求的處理階段173
6.1.5 請求的環境數據175
6.2 HTTP處理引擎176
6.2.1 處理函數原型176
6.2.2 處理函數的存儲方式176
6.2.3 內容處理函數177
6.2.4 引擎的數據結構178
6.2.5 引擎的初始化179
6.2.6 引擎的運行機制181
6.2.7 日志階段的處理182
6.3 HTTP過濾引擎183
6.3.1 過濾函數原型183
6.3.2 過濾函數鏈表184
6.3.3 過濾函數的順序185
6.3.4 過濾鏈表的運行機制187
6.3.5 請求體過濾188
6.4 Nginx模塊源碼分析188
6.4.1 ngx_http_static_module188
6.4.2 ngx_http_not_modified_filter_ module189
6.5 C++封裝190
6.5.1 NgxModuleCtx191
6.5.2 NgxHttpCoreModule193
6.5.3 NgxFilter195
6.6 總結197
第7章 Nginx HTTP請求處理199
7.1 HTTP狀態碼199
7.2 請求結構體200
7.3 請求行201
7.3.1 請求方法201
7.3.2 協議版本號202
7.3.3 資源標識符202
7.4 請求頭203
7.5 請求體204
7.5.1 結構定義205
7.5.2 操作函數205
7.6 響應頭206
7.6.1 結構定義206
7.6.2 操作函數207
7.7 響應體207
7.8 C++封裝208
7.8.1 NgxHeaders208
7.8.2 NgxRequestBody211
7.8.3 NgxRequest212
7.8.4 NgxResponse213
7.9 開發HTTP處理模塊216
7.9.1 模塊設計216
7.9.2 配置信息類217
7.9.3 業務邏輯類217
7.9.4 模塊集成類219
7.9.5 實現源文件221
7.9.6 編譯腳本221
7.9.7 測試驗證221
7.10 開發HTTP過濾模塊222
7.10.1 模塊設計222
7.10.2 配置信息類222
7.10.3 環境數據類223
7.10.4 業務邏輯類223
7.10.5 模塊集成類227
7.10.6 實現源文件228
7.10.7 編譯腳本228
7.10.8 測試驗證228
7.11 總結229
第8章 Nginx HTTP請求轉發231
8.1 upstream框架簡介231
8.1.1 工作原理232
8.1.2 請求結構體233
8.1.3 上游結構體234
8.1.4 上游配置參數236
8.2 upstream運行機制237
8.2.1 回調函數237
8.2.2 初始化upstream239
8.2.3 設置upstream239
8.2.4 啟動upstream241
8.2.5 處理upstream數據241
8.3 load—balance運行機制242
8.3.1 結構定義243
8.3.2 初始化模塊入口247
8.3.3 初始化IP地址列表248
8.3.4 初始化算法250
8.3.5 執行算法251
8.4 Nginx模塊源碼分析251
8.4.1 ngx_http_memcached_module251
8.4.2 ngx_http_upstream_ip_hash_ module254
8.5 C++封裝257
8.5.1 NgxUpstream257
8.5.2 NgxUpstreamHelper259
8.5.3 NgxHttpUpstreamModule261
8.5.4 NgxLoadBalance263
8.6 開發upstream模塊264
8.6.1 模塊設計264
8.6.2 配置信息類264
8.6.3 業務邏輯類265
8.6.4 模塊集成類268
8.6.5 實現源文件269
8.6.6 編譯腳本269
8.6.7 測試驗證269
8.7 開發load—balance模塊270
8.7.1 模塊設計271
8.7.2 配置信息類271
8.7.3 業務邏輯類271
8.7.4 模塊集成類273
8.7.5 實現源文件275
8.7.6 編譯腳本275
8.7.7 測試驗證275
8.8 總結276
第9章 Nginx HTTP子請求277
9.1 子請求簡介277
9.1.1 工作原理278
9.1.2 請求結構體279
9.1.3 回調函數280
9.1.4 待處理請求鏈表282
9.1.5 子請求存儲結構282
9.2 子請求運行機制283
9.2.1 創建子請求283
9.2.2 處理引擎287
9.2.3 數據整理288
9.3 C++封裝290
9.3.1 NgxSubRequestHandler290
9.3.2 NgxSubRequest292
9.4 數據回傳模塊293
9.4.1 模塊設計293
9.4.2 環境數據類293
9.4.3 業務邏輯類295
9.4.4 模塊集成類297
9.4.5 編譯腳本298
9.5 在模塊里使用子請求299
9.5.1 模塊設計299
9.5.2 配置信息類299
9.5.3 業務邏輯類300
9.5.4 測試驗證303
9.6 總結304
第10章 Nginx變量305
10.1 結構定義305
10.1.1 變量值305
10.1.2 變量訪問對象306
10.1.3 變量的存儲307
10.1.4 請求結構體307
10.2 運行機制308
10.2.1 注冊變量308
10.2.2 獲取變量309
10.3 C++封裝310
10.3.1 NgxVariableValue310
10.3.2 NgxVariable311
10.3.3 NgxVariables312
10.3.4 NgxVarManager313
10.3.5 NgxVariableValueProxy314
10.4 在模塊里使用變量315
10.4.1 添加變量316
10.4.2 讀寫變量317
10.5 總結317
第11章 Nginx輔助設施319
11.1 摘要算法319
11.1.1 MD5319
11.1.2 SHA—1320
11.1.3 MurmurHash321
11.1.4 C++封裝321
11.2 編碼和解碼324
11.2.1 CRC校驗324
11.2.2 Base64編碼解碼325
11.2.3 URI編碼解碼326
11.2.4 HTML和JSON編碼327
11.3 正則表達式327
11.4 共享內存328
11.4.1 結構定義328
11.4.2 操作函數329
11.4.3 C++共享內存329
11.5 定時器331
11.5.1 結構定義331
11.5.2 操作函數332
11.5.3 C++定時器事件332
11.5.4 C++定時器工廠333
11.6 總結335
第12章 Nginx與設計模式337
12.1 設計模式簡介337
12.2 框架級別的模式337
12.3 業務級別的模式339
12.4 代碼級別的模式340
12.5 總結342
第13章 結束語343
13.1 本書的遺憾343
13.2 下一步344
13.3 臨別贈言345
附錄A 推薦書目347
附錄B GDB調試簡介349
附錄C Nginx的字符串格式化351
附錄D Nginx里的void*變量353
附錄E Nginx C++模塊簡介355
附錄F Nginx Lua模塊簡介357
0.1 關於本書1
0.2 讀者對象2
0.3 讀者要求3
0.4 運行環境3
0.5 本書的結構4
0.6 如何閱讀本書6
0.7 本書的源碼6
第1章 Nginx入門7
1.1 關於Nginx7
1.1.1 歷史8
1.1.2 特點8
1.1.3 進程模型9
1.1.4 版本10
1.2 安裝Nginx11
1.2.1 准備工作11
1.2.2 快速安裝11
1.2.3 運行命令12
1.2.4 驗證安裝13
1.2.5 定制安裝14
1.3 配置Nginx15
1.3.1 配置文件格式16
1.3.2 進程配置17
1.3.3 運行日志配置18
1.3.4 http配置18
1.3.5 server配置19
1.3.6 location配置20
1.3.7 文件訪問配置21
1.3.8 upstream配置22
1.3.9 變量22
1.4 總結24
第2章 Nginx開發准備25
2.1 開發環境25
2.1.1 C++標准25
2.1.2 Boost程序庫26
2.2 Nginx的目錄結構26
2.3 Nginx源碼的特點27
2.3.1 代碼風格28
2.3.2 代碼優化28
2.3.3 面向對象思想28
2.4 在Nginx里使用C++29
2.4.1 實現原則29
2.4.2 代碼風格29
2.4.3 編譯腳本30
2.5 基本的C++包裝類32
2.5.1 類定義32
2.5.2 構造和析構33
2.5.3 成員函數33
2.6 總結34
第3章 Nginx基礎設施35
3.1 頭文件35
3.2 整數類型36
3.2.1 標准整數類型36
3.2.2 自定義整數類型36
3.2.3 無效值37
3.2.4 C++封裝38
3.3 錯誤處理41
3.3.1 錯誤碼定義41
3.3.2 C++異常41
3.4 內存池44
3.4.1 結構定義44
3.4.2 操作函數45
3.4.3 C++封裝45
3.4.4 清理機制48
3.4.5 C++內存分配器50
3.5 字符串52
3.5.1 結構定義52
3.5.2 操作函數53
3.5.3 C++封裝55
3.6 時間與日期58
3.6.1 時間結構定義58
3.6.2 時間操作函數58
3.6.3 日期結構定義59
3.6.4 日期操作函數60
3.6.5 C++封裝時間61
3.6.6 C++封裝日期62
3.7 運行日志64
3.7.1 結構定義65
3.7.2 操作函數65
3.7.3 C++封裝66
3.8 總結68
第4章 Nginx高級數據結構71
4.1 動態數組71
4.1.1 結構定義71
4.1.2 操作函數73
4.1.3 C++封裝73
4.2 單向鏈表76
4.2.1 結構定義77
4.2.2 操作函數78
4.2.3 C++迭代器79
4.2.4 C++封裝鏈表81
4.3 雙端隊列84
4.3.1 結構定義84
4.3.2 操作函數85
4.3.3 C++節點87
4.3.4 C++迭代器89
4.3.5 C++封裝隊列90
4.4 緩沖區95
4.4.1 結構定義95
4.4.2 操作函數97
4.4.3 C++封裝98
4.5 數據塊鏈100
4.5.1 結構定義100
4.5.2 操作函數101
4.5.3 C++節點101
4.5.4 C++迭代器103
4.5.5 C++封裝數據塊鏈105
4.6 鍵值對107
4.6.1 簡單鍵值對107
4.6.2 散列表鍵值對107
4.7 總結108
第5章 Nginx開發綜述111
5.1 最簡單的Nginx模塊111
5.1.1 模塊設計112
5.1.2 配置解析112
5.1.3 處理函數114
5.1.4 模塊集成116
5.1.5 編譯腳本和命令117
5.1.6 測試驗證118
5.2 Nginx開發基本流程119
5.2.1 設計119
5.2.2 開發119
5.2.3 編譯120
5.2.4 測試驗證120
5.2.5 調優121
5.3 Nginx的模塊121
5.3.1 模塊的數據結構121
5.3.2 模塊的種類123
5.3.3 http模塊124
5.3.4 模塊的類圖124
5.3.5 模塊的組織形式125
5.4 Nginx的配置127
5.4.1 結構定義128
5.4.2 配置解析的基本流程131
5.4.3 配置數據的存儲模型133
5.4.4 訪問配置數據138
5.4.5 確定配置數據的位置138
5.4.6 配置解析函數140
5.4.7 配置數據的合並141
5.4.8 配置指令的類型142
5.5 Nginx模塊源碼分析143
5.5.1 ngx_core_module143
5.5.2 ngx_errlog_module146
5.6 Nginx的編譯腳本147
5.6.1 運行機制147
5.6.2 使用的變量148
5.7 C++封裝模塊信息149
5.7.1 NgxModuleConfig149
5.7.2 NgxModule153
5.8 C++封裝配置解析155
5.8.1 NgxCommand155
5.8.2 NgxTake155
5.8.3 NGX_MODULE_NULL157
5.9 C++開發Nginx模塊158
5.9.1 C++模塊的基本組成158
5.9.2 配置信息類159
5.9.3 業務邏輯類160
5.9.4 模塊集成類162
5.9.5 實現源文件164
5.9.6 增加更多功能164
5.10 總結165
第6章 Nginx HTTP框架綜述169
6.1 HTTP框架簡介169
6.1.1 模塊分類169
6.1.2 處理流程170
6.1.3 請求結構體172
6.1.4 請求的處理階段173
6.1.5 請求的環境數據175
6.2 HTTP處理引擎176
6.2.1 處理函數原型176
6.2.2 處理函數的存儲方式176
6.2.3 內容處理函數177
6.2.4 引擎的數據結構178
6.2.5 引擎的初始化179
6.2.6 引擎的運行機制181
6.2.7 日志階段的處理182
6.3 HTTP過濾引擎183
6.3.1 過濾函數原型183
6.3.2 過濾函數鏈表184
6.3.3 過濾函數的順序185
6.3.4 過濾鏈表的運行機制187
6.3.5 請求體過濾188
6.4 Nginx模塊源碼分析188
6.4.1 ngx_http_static_module188
6.4.2 ngx_http_not_modified_filter_ module189
6.5 C++封裝190
6.5.1 NgxModuleCtx191
6.5.2 NgxHttpCoreModule193
6.5.3 NgxFilter195
6.6 總結197
第7章 Nginx HTTP請求處理199
7.1 HTTP狀態碼199
7.2 請求結構體200
7.3 請求行201
7.3.1 請求方法201
7.3.2 協議版本號202
7.3.3 資源標識符202
7.4 請求頭203
7.5 請求體204
7.5.1 結構定義205
7.5.2 操作函數205
7.6 響應頭206
7.6.1 結構定義206
7.6.2 操作函數207
7.7 響應體207
7.8 C++封裝208
7.8.1 NgxHeaders208
7.8.2 NgxRequestBody211
7.8.3 NgxRequest212
7.8.4 NgxResponse213
7.9 開發HTTP處理模塊216
7.9.1 模塊設計216
7.9.2 配置信息類217
7.9.3 業務邏輯類217
7.9.4 模塊集成類219
7.9.5 實現源文件221
7.9.6 編譯腳本221
7.9.7 測試驗證221
7.10 開發HTTP過濾模塊222
7.10.1 模塊設計222
7.10.2 配置信息類222
7.10.3 環境數據類223
7.10.4 業務邏輯類223
7.10.5 模塊集成類227
7.10.6 實現源文件228
7.10.7 編譯腳本228
7.10.8 測試驗證228
7.11 總結229
第8章 Nginx HTTP請求轉發231
8.1 upstream框架簡介231
8.1.1 工作原理232
8.1.2 請求結構體233
8.1.3 上游結構體234
8.1.4 上游配置參數236
8.2 upstream運行機制237
8.2.1 回調函數237
8.2.2 初始化upstream239
8.2.3 設置upstream239
8.2.4 啟動upstream241
8.2.5 處理upstream數據241
8.3 load—balance運行機制242
8.3.1 結構定義243
8.3.2 初始化模塊入口247
8.3.3 初始化IP地址列表248
8.3.4 初始化算法250
8.3.5 執行算法251
8.4 Nginx模塊源碼分析251
8.4.1 ngx_http_memcached_module251
8.4.2 ngx_http_upstream_ip_hash_ module254
8.5 C++封裝257
8.5.1 NgxUpstream257
8.5.2 NgxUpstreamHelper259
8.5.3 NgxHttpUpstreamModule261
8.5.4 NgxLoadBalance263
8.6 開發upstream模塊264
8.6.1 模塊設計264
8.6.2 配置信息類264
8.6.3 業務邏輯類265
8.6.4 模塊集成類268
8.6.5 實現源文件269
8.6.6 編譯腳本269
8.6.7 測試驗證269
8.7 開發load—balance模塊270
8.7.1 模塊設計271
8.7.2 配置信息類271
8.7.3 業務邏輯類271
8.7.4 模塊集成類273
8.7.5 實現源文件275
8.7.6 編譯腳本275
8.7.7 測試驗證275
8.8 總結276
第9章 Nginx HTTP子請求277
9.1 子請求簡介277
9.1.1 工作原理278
9.1.2 請求結構體279
9.1.3 回調函數280
9.1.4 待處理請求鏈表282
9.1.5 子請求存儲結構282
9.2 子請求運行機制283
9.2.1 創建子請求283
9.2.2 處理引擎287
9.2.3 數據整理288
9.3 C++封裝290
9.3.1 NgxSubRequestHandler290
9.3.2 NgxSubRequest292
9.4 數據回傳模塊293
9.4.1 模塊設計293
9.4.2 環境數據類293
9.4.3 業務邏輯類295
9.4.4 模塊集成類297
9.4.5 編譯腳本298
9.5 在模塊里使用子請求299
9.5.1 模塊設計299
9.5.2 配置信息類299
9.5.3 業務邏輯類300
9.5.4 測試驗證303
9.6 總結304
第10章 Nginx變量305
10.1 結構定義305
10.1.1 變量值305
10.1.2 變量訪問對象306
10.1.3 變量的存儲307
10.1.4 請求結構體307
10.2 運行機制308
10.2.1 注冊變量308
10.2.2 獲取變量309
10.3 C++封裝310
10.3.1 NgxVariableValue310
10.3.2 NgxVariable311
10.3.3 NgxVariables312
10.3.4 NgxVarManager313
10.3.5 NgxVariableValueProxy314
10.4 在模塊里使用變量315
10.4.1 添加變量316
10.4.2 讀寫變量317
10.5 總結317
第11章 Nginx輔助設施319
11.1 摘要算法319
11.1.1 MD5319
11.1.2 SHA—1320
11.1.3 MurmurHash321
11.1.4 C++封裝321
11.2 編碼和解碼324
11.2.1 CRC校驗324
11.2.2 Base64編碼解碼325
11.2.3 URI編碼解碼326
11.2.4 HTML和JSON編碼327
11.3 正則表達式327
11.4 共享內存328
11.4.1 結構定義328
11.4.2 操作函數329
11.4.3 C++共享內存329
11.5 定時器331
11.5.1 結構定義331
11.5.2 操作函數332
11.5.3 C++定時器事件332
11.5.4 C++定時器工廠333
11.6 總結335
第12章 Nginx與設計模式337
12.1 設計模式簡介337
12.2 框架級別的模式337
12.3 業務級別的模式339
12.4 代碼級別的模式340
12.5 總結342
第13章 結束語343
13.1 本書的遺憾343
13.2 下一步344
13.3 臨別贈言345
附錄A 推薦書目347
附錄B GDB調試簡介349
附錄C Nginx的字符串格式化351
附錄D Nginx里的void*變量353
附錄E Nginx C++模塊簡介355
附錄F Nginx Lua模塊簡介357
序
緣起
最早接觸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是目前這個星球上所能獲得的最強勁的Web服務器(沒有之一),同時也是目前最成熟、最優秀的TCP/HTTP服務器開發框架。
Nginx 資源消耗低,並發處理性能高,配置靈活,能夠連接CGI、PHP、MySQL、Memcached等多種后端,還有着出色的負載均衡能力,可以整合封裝各 種service,構建穩定高效的服務。如今Nginx已經成為了網站架構里不可或缺的關鍵組件,廣泛應用於國內外許多大型IT企業內部。每一個繁忙的網 站背后,可能都有Nginx默默工作的身影。
在Nginx出現之前,使用C/C++開發Web服務器是項比較「痛苦」的工作,雖然有很多網絡程序 庫可以使用(例如ACE、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的作者Igor Sysoev,沒有他就不會有如此優秀的Web服務器,也就不會有本書的誕生。
親情永遠是人生命中最值得珍惜的部分,我要感謝父母多年來的養育之恩和「后勤」工作,感謝妻子在生活中的陪伴(但因為頻繁的加班常常缺少相處的時間),感謝即將上小學的女兒,願你們能夠永遠幸福快樂。
我還要感謝工作中共同奮斗拼搏的諸多同事,從他們那里我獲取到了很多的經驗和知識,度過了很多難忘的歲月,和他們在一起讓工作超越了謀生的手段變成了一種享受。
最后感謝讀者選擇本書,希望讀者能夠在閱讀過程中有所收獲,在Nginx開發過程中獲得樂趣。
您的朋友 羅劍鋒
2015年8月18日 於 北京 酒仙橋
最早接觸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是目前這個星球上所能獲得的最強勁的Web服務器(沒有之一),同時也是目前最成熟、最優秀的TCP/HTTP服務器開發框架。
Nginx 資源消耗低,並發處理性能高,配置靈活,能夠連接CGI、PHP、MySQL、Memcached等多種后端,還有着出色的負載均衡能力,可以整合封裝各 種service,構建穩定高效的服務。如今Nginx已經成為了網站架構里不可或缺的關鍵組件,廣泛應用於國內外許多大型IT企業內部。每一個繁忙的網 站背后,可能都有Nginx默默工作的身影。
在Nginx出現之前,使用C/C++開發Web服務器是項比較「痛苦」的工作,雖然有很多網絡程序 庫可以使用(例如ACE、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的作者Igor Sysoev,沒有他就不會有如此優秀的Web服務器,也就不會有本書的誕生。
親情永遠是人生命中最值得珍惜的部分,我要感謝父母多年來的養育之恩和「后勤」工作,感謝妻子在生活中的陪伴(但因為頻繁的加班常常缺少相處的時間),感謝即將上小學的女兒,願你們能夠永遠幸福快樂。
我還要感謝工作中共同奮斗拼搏的諸多同事,從他們那里我獲取到了很多的經驗和知識,度過了很多難忘的歲月,和他們在一起讓工作超越了謀生的手段變成了一種享受。
最后感謝讀者選擇本書,希望讀者能夠在閱讀過程中有所收獲,在Nginx開發過程中獲得樂趣。
您的朋友 羅劍鋒
2015年8月18日 於 北京 酒仙橋
網路書店
類別
折扣
價格
-
新書$474