內容簡介
本書主要講解了Nginx 在反向代理和套用開發中的作用,閱讀本書可以了解Nginx 在網際網路開發中扮演的多個角色,充分利用這些角色的各項功能有助於提升服務的整體性能。本書所介紹的大部分功能是通過Nginx+Lua 進行開發和配置的,但並不要求讀者精通Lua,在必要的位置,本書會對Lua 進行選擇性講解。涉及實戰的內容會有配套源碼,方便讀者學習和使用。本書適合廣大運維人員和開發人員學習,對使用Nginx 完成各種服務架構感興趣的架構師也可以閱讀本書。閱讀本書需要有對Nginx 的初級或中級配置經驗。
作者簡介
·王力·折800運維架構師,Nginx開發工程師,具有多年網際網路相關項目的開發經驗。喜歡使用小眾技術完成運維、開發和測試任務,擅長通過架構設計降低開發難度,擅長搭建Nginx高性能服務。·湯永全·折800運維主管,具有多年網際網路相關項目的運維工作經驗。歷經傳統運維和網際網路運維,一步一個腳印,積累了不少運維相關的經驗和感悟。活躍於成都運維管理人員的線下組織“運維羅漢堂”。
圖書目錄
第1 章 Nginx 學前必知. 1
1.1 HTTP 請求報文. 1
1.2 HTTP 回響報文. 2
1.3 安裝Nginx. 2
1.4 支持HTTPS....... 4
1.5 添加模組.... 4
1.6 小結..... 4
第2 章 基礎配置..... 5
2.1 Nginx 指令和指令塊 5
2.2 Nginx 基本配置說明 6
2.2.1 main 配置.. 6
2.2.2 與客戶端有關的配置....... 7
2.2.3 server 塊..... 7
2.2.4 location 塊.. 8
2.3 include 的使用... 9
2.4 常見配置.... 9
2.4.1 常見配置註解..10
2.4.2 常見配置實戰技巧..11
2.5 內置變數...13
2.5.1 常見內置變數..13
2.5.2 常見內置變數實戰技巧...15
2.6 小結....16
第3 章 強化基礎配置....17
3.1 牢記Context .....17
3.2 獲取請求的IP 地址18
3.2.1 獲取用戶的真實IP 地址.18
3.2.2 防止IP 地址偽造.....19
3.2.3 後端伺服器對IP 地址的需求.19
3.3 管理請求的行為......20
3.3.1 限制IP 地址的訪問.20
3.3.2 auth 身份驗證...21
3.3.3 利用LDAP 服務加強安全......22
3.3.4 satisfy 二選一的訪問限制功能.......23
3.4 proxy 代理.23
3.4.1 proxy_pass 請求代理規則24
3.4.2 減少後端伺服器的網路開銷...24
3.4.3 控制請求頭和請求體......25
3.4.4 控制請求和後端伺服器的互動時間.......26
3.5 upstream 使用手冊..26
3.5.1 代理多台伺服器......27
3.5.2 故障轉移..28
3.5.3 負載均衡..29
3.5.4 通過hash 分片提升快取命中率......29
3.5.5 利用長連線提升性能......30
3.5.6 利用resolver 加速對內部域名的訪問....31
3.6 rewrite 使用手冊......32
3.6.1 內部重定向......32
3.6.2 域名跳轉..33
3.6.3 跳轉POST 請求.......34
3.6.4 設定變數的值..34
3.7 限速白名單.......35
3.8 日誌....36
3.8.1 記錄自定義變數......36
3.8.2 日誌格式規範..36
3.8.3 日誌存儲..37
3.9 HTTP 執行階段38
3.10 小結..39
第4 章 常用模組精解....40
4.1 定製HTTP 頭信息..40
4.1.1 使用ngx_http_headers_module 設定回響頭...40
4.1.2 使用headers-more-nginx 控制請求頭和回響頭.....43
4.2 第三方模組set-misc-nginx....45
4.2.1 設定變數..46
4.2.2 防止SQL 注入.46
4.2.3 字元串非轉義和轉義......47
4.2.4 基於鍵值的集群分片......48
4.2.5 base 編碼..48
4.2.6 md5 編碼..50
4.2.7 生成隨機數......50
4.2.8 本地時間的輸出......52
4.2.9 實戰經驗..52
4.3 圖片的處理.......53
4.3.1 image_filter 圖片處理......53
4.3.2 採用漸進式方式打開JPEG 圖片.55
4.3.3 WebP 格式..56
4.3.4 最佳化圖片....56
4.3.5 實戰經驗:動態切圖.....58
4.4 TCP 和UDP 代理.....58
4.4.1 代理配置說明...58
4.4.2 DNS 服務的反向代理.....62
4.4.3 MySQL 集群代理配置....62
4.4.4 實戰經驗....63
4.5 常用模組介紹.....63
4.5.1 基於訪問IP 地址跳轉到對應城市.....63
4.5.2 修改回響內容...65
4.5.3 零像素檔案的生成及其作用.66
4.5.4 圖片的防盜鏈...67
4.6 小結.68
第5 章 快取系統69
5.1 快取配置說明.....69
5.2 控制快取有效期71
5.3 性能最佳化......72
5.3.1 快取未命中的最佳實踐..72
5.3.2 橫向擴展最佳實踐..75
5.3.3 避免硬碟I/O 阻塞...76
5.3.4 集群模式....77
5.4 高可用方案..77
5.5 proxy_cache 配置模板....78
5.6 小結.81
第6 章 引入Lua.82
6.1 引入Lua 的原因82
6.2 Lua 和LuaJIT .....83
6.3 環境搭建......83
6.4 Lua 的數據類型.84
6.4.1 類型說明....84
6.4.2 類型示例....85
6.5 表達式....89
6.5.4 字元串連線和字元串長度計算....92
6.5.5 運算符優先權...93
6.6 變數.93
6.6.1 全局變數....94
6.6.2 局部變數....94
6.6.3 變數賦值....94
6.7 流程控制......95
6.7.1 if-else ...95
6.7.2 for 循環96
6.7.3 while 循環...97
6.7.4 break 和return ...97
6.8 函式.98
6.8.1 函式格式....98
6.8.2 傳參方式....99
6.8.3 函式的創建位置....100
6.9 模組......100
6.9.1 模組格式..101
6.9.2 載入模組..101
6.10 Lua 常見操作.102
6.10.1 操作table ......102
6.10.2 定義字元串...103
6.10.3 字元串連線...104
6.11 引入Lua 的插曲...104
6.12 小結....105
第7 章 Lua-Nginx-Module 常用指令....106
7.1 Nginx 和OpenResty ......106
7.2 安裝Ngx_Lua ..107
7.3 牢記Context .....108
7.4 Hello World 108
7.5 避免I/O 阻塞....109
7.6 定義模組搜尋路徑.109
7.6.1 定義Lua 模組的搜尋路徑...109
7.6.2 定義C 模組的搜尋路徑......110
7.7 讀/寫Nginx 的內置變數.....110
7.8 控制請求頭111
7.8.1 添加請求頭.....111
7.8.2 清除請求頭.....112
7.8.3 獲取請求頭.....112
7.9 控制回響頭113
7.9.1 獲取回響頭.....113
7.9.2 修改回響頭.....114
7.9.3 清除回響頭.....116
7.10 讀取請求體.....116
7.10.1 強制獲取請求體..116
7.10.2 用同步非阻塞方式獲取請求體117
7.10.3 使用場景示例......118
7.10.4 使用建議121
7.11 輸出回響體.....121
7.11.1 異步傳送回響體..121
7.11.2 同步傳送回響體..122
7.12 正則表達式.....124
7.12.1 單一捕獲124
7.12.2 全部捕獲125
7.12.3 更高效的匹配和捕獲.126
7.12.4 替換數據128
7.12.5 轉義符號129
7.13 子請求130
7.13.1 請求方法130
7.13.2 單一子請求...130
7.13.3 並發子請求...134
7.14 獲取Nginx 的環境變數.....135
7.14.1 獲取環境所在的模組..135
7.14.2 確認調試模式......136
7.14.3 獲取prefix 路徑...136
7.14.4 獲取Nginx 的版本號...136
7.14.5 獲取configure 信息.....136
7.14.6 獲取Ngx_Lua 的版本號......137
7.14.7 判斷worker 進程是否退出.137
7.14.8 獲取worker 進程的ID 137
7.14.9 獲取worker 進程的數量.....137
7.15 定時任務.......138
7.15.1 創建定時任務......138
7.15.2 性能最佳化......140
7.15.3 禁用的Lua API....141
7.16 常用指令.......142
7.16.1 請求重定向..142
7.16.2 日誌記錄......144
7.16.3 請求中斷處理......146
7.17 提升開發和測試效率.149
7.17.1 斷開客戶端連線..149
7.17.2 請求休眠......150
7.17.3 獲取系統時間......150
7.17.4 編碼與解碼..152
7.17.5 防止SQL 注入.....154
7.17.6 判斷是否為子請求......155
7.17.7 設定MIME 類型..156
7.18 小結156
第8 章 Ngx_Lua 的執行階段....157
8.1 init_by_lua_block...157
8.1.1 階段說明157
8.1.2 初始化配置....158
8.1.3 控制初始值....159
8.1.4 init_by_lua_file.......160
8.1.5 可使用的Lua API 指令.160
8.2 init_worker_by_lua_block ....160
8.2.1 階段說明160
8.2.2 啟動Nginx 的定時任務.161
8.2.3 動態進行後端健康檢查.162
8.3 set_by_lua_block....165
8.3.1 階段說明165
8.3.2 變數賦值165
8.3.3 rewrite 階段的混用模式166
8.3.4 阻塞事件167
8.3.5 被禁用的Lua API 指令.167
8.4 rewrite_by_lua_block ....168
8.4.1 階段說明168
8.4.2 利用rewrite_by_lua_no_postpone 改變執行順序.168
8.4.3 階段控制169
8.5 access_by_lua_block......169
8.5.1 階段說明169
8.5.2 利用access_by_lua_no_postpone 改變執行順序..170
8.5.3 階段控制170
8.5.4 動態配置黑白名單170
8.6 content_by_lua_block....170
8.6.1 階段說明170
8.6.2 動態調整執行檔案的路徑.....171
8.7 balancer_by_lua_block..171
8.7.1 階段說明171
8.7.2 被禁用的Lua API 指令.172
8.8 header_filter_by_lua_block ..172
8.8.1 階段說明172
8.8.2 被禁用的Lua API 指令.173
8.9 body_filter_by_lua_block .....173
8.9.1 階段說明173
8.9.2 控制回響體數據....173
8.9.3 被禁用的Lua API 指令.175
8.10 log_by_lua_block.176
8.10.1 階段說明......176
8.10.2 被禁用的Lua API 指令.......176
8.11 Lua 和ngx.ssl .......177
8.12 Ngx_Lua 執行階段......177
8.13 小結180
第9 章 Nginx 與資料庫的互動.181
9.1 安裝cjson181
9.2 與MySQL 互動.....183
9.2.1 安裝lua-resty-mysql 模組......183
9.2.2 讀取MySQL 數據.183
9.2.3 執行多條SQL 語句.......187
9.2.4 防止SQL 注入.......189
9.3 與Redis 互動..189
9.3.1 安裝lua-resty-redis 189
9.3.2 讀/寫Redis .....189
9.3.3 管道命令191
9.3.4 密碼登錄193
9.3.5 其他執行命令194
9.4 與資料庫互動的常見問題...194
9.4.1 連線池....194
9.4.2 讀/寫分離.......197
9.4.3 分離配置檔案和代碼....197
9.5 小結..198
第10 章 快取利器199
10.1 worker 進程的共享記憶體....200
10.1.1 創建共享記憶體區域......200
10.1.2 操作共享記憶體......201
10.1.3 製造訊息佇列......205
10.1.4 lua-resty-core 207
10.1.5 配置環境......208
10.2 Lua 模組下的共享記憶體......209
10.2.1 安裝lua-resty-lrucache.209
10.2.2 使用lua-resty-lrucache 進行快取的方法....209
10.3 當前請求在各執行階段間的數據共享...213
10.3.1 ngx.ctx 的使用......213
10.3.2 子請求和內部重定向的快取區別.......214
10.4 利用共享記憶體配置動態IP 地址認證.....215
10.5 快取和資料庫的互動.218
10.5.1 從資料庫獲取數據......218
10.5.2 避免出現因快取失效引起的“風暴”.......223
10.6 小結228
第11 章 動態管理upstream.....229
11.1 實戰需求分析.......230
11.2 ngx_http_dyups_module .....230
11.2.1 安裝ngx_http_dyups_module......230
11.2.2 動態管理upstream.......230
11.2.3 確保upstream 數據的完整性......232
11.3 nginx-upsync-module ..233
11.3.1 安裝nginx-upsync-module 和Consul..233
11.3.2 Consul 的鍵值操作......234
11.3.3 動態管理upstream.......235
11.3.4 驗證動態配置功能......237
11.3.5 高可用、高並發設計..237
11.4 基於balancer_by_lua_block 的靈活控制.......238
11.5 小結239
第12 章 Nginx 日誌分析系統...240
12.1 實戰需求分析......240
12.2 ngxtop 實時分析..241
12.3 Flume 方案的日誌分析......243
12.4 智慧型化nginx_log_analysis 244
12.4.1 架構重構......244
12.4.2 日誌遠程傳輸......245
12.4.3 時序資料庫..245
12.4.4 日誌規則設計......245
12.5 lua-resty-logger-socket 傳輸方案......246
12.5.1 安裝lua-resty-logger-socket.246
12.5.2 遠程傳輸配置......247
12.5.3 參數解讀......248
12.6 時序資料庫InfluxDB.249
12.6.1 安裝InfluxDB ......249
12.6.2 基本概念和操作..249
12.6.3 數據分析之查詢函式..250
12.6.4 數據存放之保留策略..251
12.6.5 定時任務之連續查詢..251
12.6.6 客戶端操作之API.......252
12.6.7 使用UDP 模式傳輸數據.....253
12.7 利用lua-resty-http 實現API 互動....254
12.7.1 安裝lua-resty-http254
12.7.2 使用方式......254
12.8 提升InfluxDB 性能....255
12.9 小結255
第13 章 靜態容災系統.......256
13.1 荊棘之路.......257
13.2 設計之路.......259
13.3 架構流程圖...261
13.3.1 反向代理系統......261
13.3.2 日誌分析系統......261
13.3.3 後台系統......261
13.3.4 爬蟲系統......262
13.3.5 容災的快取系統..262
13.3.6 時間版本的用途..263
13.3.7 異地容災......263
13.4 核心代碼解說......264
13.4.1 Ngx_Lua 套用......264
13.4.2 爬蟲和日誌系統的關係.......266
13.4.3 全部容災和部分容災功能...266
13.5 靜態容災的智慧型關閉方案267
13.5.1 從日誌分析系統中複製請求.......267
13.5.2 利用goreplay 複製流量.......267
13.5.3 Nginx 的鏡像功能268
13.5.4 灰度驗證容災系統快取.......269
13.6 小結269
第14 章 深入挖掘反向代理......270
14.1 驗證碼防禦中心..270
14.2 鑒權管理中心......272
14.2.1 利用auth_request 管理鑒權272
14.2.2 利用Ngx_Lua 子請求實現鑒權功能..273
14.3 並行訪問.......274
14.3.1 輕執行緒的啟動和終止..275
14.3.2 等待和終止輕執行緒......276
14.3.3 URL 的外部合併和內部並發......278
14.3.4 使用cosocket 實現外部訪問.......281
14.4 小結281
第15 章 爬蟲.282
15.1 區分搜尋引擎爬蟲和惡意爬蟲282
15.2 應對搜尋引擎爬蟲......284
15.2.1 搜尋引擎的User-Agent.......284
15.2.2 Robots 協定..285
15.2.3 控制搜尋引擎爬蟲實戰.......286
15.3 應對惡意爬蟲......288
15.3.1 發現惡意爬蟲......288
15.3.2 抵禦惡意爬蟲之禁止訪問...289
15.3.3 抵禦惡意爬蟲之驗證碼攔截.......290
15.4 小插曲——使用假數據迷惑惡意爬蟲...290
15.5 小結291
第16 章 性能分析和最佳化...292
16.1 性能分析場景搭建......292
16.1.1 安裝SystemTap ...292
16.1.2 LuaJIT 的Debug 模式..293
16.1.3 開啟PCRE 的Debug 模式..294
16.1.4 分析工具下載......294
16.1.5 找出不支持Debug 模式的lib 庫295
16.2 流量複製.......295
16.3 各項指標分析和最佳化建議295
16.3.1 連線池使用狀態分析..295
16.3.2 找出讀/寫頻繁的檔案.297
16.3.3 執行階段耗時分析......297
16.3.4 HTTP 連線數和檔案打開數分析298
16.3.5 找出CPU“偷竊者”..298
16.3.6 正則表達式耗時分析..299
16.3.7 找出消耗CPU 資源較多的指令.301
16.3.8 利用火焰圖展示和分析數據.......303
16.4 檢查全局變數......305
16.5 小結305
第17 章 值得擁有的OpenResty.....306
17.1 OPM.......307
17.2 使用DNS 提升訪問效率...309
17.3 TCP 和UDP 服務310
17.4 多層級快取...312
17.5 lua-resty-core 擴展.......313
17.5.1 字元串分割..313
17.5.2 Nginx 進程管理....313
17.6 全局唯一標識符UUID......315
17.7 “全家福”awesome-resty 316
17.8 OpenResty,未來!....316
第18 章 開發環境下的常見問題......317
18.1 被截斷的回響體..317
18.2 “邪惡”的if .......317
18.3 “貪婪”的正則匹配.318
18.4 規範HTTP 狀態碼......319
18.5 規範URL......319
18.6 proxy_set_header 的誤操作.......320
18.7 開發環境下的證書問題.....320
18.8 深層次的錯誤重定向.323
18.9 壓測環境下的限速和短連線....323
18.10 小結......323