內容提要
《億級流量網站架構核心技術》一書總結並梳理了億級流量網站高可用和高並發原則,通過實例詳細介紹了如何落地這些原則。本書分為四部分:概述、高可用原則、高並發原則、案例實戰。從負載均衡、限流、降級、隔離、逾時與重試、回滾機制、壓測與預案、快取、池化、異步化、擴容、佇列等多方面詳細介紹了億級流量網站的架構核心技術,讓讀者看後能快速運用到實踐項目中。
不管是軟體開發人員,還是運維人員,通過閱讀《億級流量網站架構核心技術》都能系統地學習實現億級流量網站的架構核心技術,並收穫解決系統問題的思路和方法。
目錄
第1部分概述 1
1 交易型系統設計的一些原則 2
1.1 高並發原則 3
1.1.1 無狀態 3
1.1.2 拆分 3
1.1.3 服務化 4
1.1.4 訊息佇列 4
1.1.5 數據異構 6
1.1.6 快取銀彈 7
1.1.7 並發化 9
1.2 高可用原則 10
1.2.1 降級 10
1.2.2 限流 11
1.2.3 切流量 12
1.2.4 可回滾 12
1.3 業務設計原則 12
1.3.1 防重設計 13
1.3.2 冪等設計 13
1.3.3 流程可定義 13
1.3.4 狀態與狀態機 13
1.3.5 後台系統操作可反饋 14
1.3.6 後台系統審批化 14
1.3.7 文檔和注釋 14
1.3.8 備份 14
1.4 總結 14
第2部分高可用 17
2 負載均衡與反向代理 18
2.1 upstream配置 20
2.2 負載均衡算法 21
2.3 失敗重試 23
2.4 健康檢查 24
2.4.1 TCP心跳檢查 24
2.4.2 HTTP心跳檢查 25
2.5 其他配置 25
2.5.1 域名上游伺服器 25
2.5.2 備份上游伺服器 26
2.5.3 不可用上游伺服器 26
2.6 長連線 26
2.7 HTTP反向代理示例 29
2.8 HTTP動態負載均衡 30
2.8.1 Consul+Consul-template 31
2.8.2 Consul+OpenResty 35
2.9 Nginx四層負載均衡 39
2.9.1 靜態負載均衡 39
2.9.2 動態負載均衡 41
參考資料 42
3 隔離術 43
3.1 執行緒隔離 43
3.2 進程隔離 45
3.3 集群隔離 45
3.4 機房隔離 46
3.5 讀寫隔離 47
3.6 動靜隔離 48
3.7 爬蟲隔離 49
3.8 熱點隔離 50
3.9 資源隔離 50
3.10 使用Hystrix實現隔離 51
3.10.1 Hystrix簡介 51
3.10.2 隔離示例 52
3.11 基於Servlet 3實現請求隔離 56
3.11.1 請求解析和業務處理執行緒池分離 57
3.11.2 業務執行緒池隔離 58
3.11.3 業務執行緒池監控/運維/降級 58
3.11.4 如何使用Servlet 3異步化 59
3.11.5 一些Servlet 3異步化壓測數據 64
4 限流詳解 66
4.1 限流算法 67
4.1.1 令牌桶算法 67
4.1.2 漏桶算法 68
4.2 套用級限流 69
4.2.1 限流總並發/連線/請求數 69
4.2.2 限流總資源數 70
4.2.3 限流某個接口的總並發/請求數 70
4.2.4 限流某個接口的時間窗請求數 70
4.2.5 平滑限流某個接口的請求數 71
4.3 分散式限流 75
4.3.1 Redis+Lua實現 76
4.3.2 Nginx+Lua實現 77
4.4 接入層限流 78
4.4.1 ngx_http_limit_conn_module 78
4.4.2 ngx_http_limit_req_module 80
4.4.3 lua-resty-limit-traffic 88
4.5 節流 90
4.5.1 throttleFirst/throttleLast 90
4.5.2 throttleWithTimeout 91
參考資料 92
5 降級特技 93
5.1 降級預案 93
5.2 自動開關降級 95
5.2.1 逾時降級 95
5.2.2 統計失敗次數降級 95
5.2.3 故障降級 95
5.2.4 限流降級 95
5.3 人工開關降級 96
5.4 讀服務降級 96
5.5 寫服務降級 97
5.6 多級降級 98
5.7 配置中心 100
5.7.1 套用層API封裝 100
5.7.2 配置檔案實現開關配置 101
5.7.3 配置中心實現開關配置 102
5.8 使用Hystrix實現降級 106
5.9 使用Hystrix實現熔斷 108
5.9.1 熔斷機制實現 108
5.9.2 配置示例 112
5.9.3 採樣統計 113
6 逾時與重試機制 117
6.1 簡介 117
6.2 代理層逾時與重試 119
6.2.1 Nginx 119
6.2.2 Twemproxy 126
6.3 Web容器逾時 127
6.4 中間件客戶端逾時與重試 127
6.5 資料庫客戶端逾時 131
6.6 NoSQL客戶端逾時 134
6.7 業務逾時 135
6.8 前端Ajax逾時 135
6.9 總結 136
6.10 參考資料 137
7 回滾機制 139
7.1 事務回滾 139
7.2 代碼庫回滾 140
7.3 部署版本回滾 141
7.4 數據版本回滾 142
7.5 靜態資源版本回滾 143
8 壓測與預案 145
8.1 系統壓測 145
8.1.1 線下壓測 146
8.1.2 線上壓測 146
8.2 系統最佳化和容災 147
8.3 應急預案 148
第3部分高並發 153
9 套用級快取 154
9.1 快取簡介 154
9.2 快取命中率 155
9.3 快取回收策略 155
9.3.1 基於空間 155
9.3.2 基於容量 155
9.3.3 基於時間 155
9.3.4 基於Java對象引用 156
9.3.5 回收算法 156
9.4 Java快取類型 156
9.4.1 堆快取 158
9.4.2 堆外快取 162
9.4.3 磁碟快取 162
9.4.4 分散式快取 164
9.4.5 多級快取 166
9.5 套用級快取示例 167
9.5.1 多級快取API封裝 167
9.5.2 NULL Cache 170
9.5.3 強制獲取最新數據 170
9.5.4 失敗統計 171
9.5.5 延遲報警 171
9.6 快取使用模式實踐 172
9.6.1 Cache-Aside 173
9.6.2 Cache-As-SoR 174
9.6.3 Read-Through 174
9.6.4 Write-Through 176
9.6.5 Write-Behind 177
9.6.6 Copy Pattern 181
9.7 性能測試 181
9.8 參考資料 182
10 HTTP快取 183
10.1 簡介 183
10.2 HTTP快取 184
10.2.1 Last-Modified 184
10.2.2 ETag 190
10.2.3 總結 192
10.3 HttpClient客戶端快取 192
10.3.1 主流程 195
10.3.2 清除無效快取 195
10.3.3 查找快取 196
10.3.4 快取未命中 198
10.3.5 快取命中 198
10.3.6 快取內容陳舊需重新驗證 202
10.3.7 快取內容無效需重新執行請求 205
10.3.8 快取回響 206
10.3.9 快取頭總結 207
10.4 Nginx HTTP快取設定 208
10.4.1 expires 208
10.4.2 if-modified-since 209
10.4.3 nginx proxy_pass 209
10.5 Nginx代理層快取 212
10.5.1 Nginx代理層快取配置 212
10.5.2 清理快取 215
10.6 一些經驗 216
參考資料 217
11 多級快取 218
11.1 多級快取介紹 218
11.2 如何快取數據 220
11.2.1 過期與不過期 220
11.2.2 維度化快取與增量快取 221
11.2.3 大Value快取 221
11.2.4 熱點快取 221
11.3 分散式快取與套用負載均衡 222
11.3.1 快取分散式 222
11.3.2 套用負載均衡 222
11.4 熱點數據與更新快取 223
11.4.1 單機全量快取+主從 223
11.4.2 分散式快取+套用本地熱點 224
11.5 更新快取與原子性 225
11.6 快取崩潰與快速修復 226
11.6.1 取模 226
11.6.2 一致性哈希 226
11.6.3 快速恢復 226
12 連線池執行緒池詳解 227
12.1 資料庫連線池 227
12.1.1 DBCP連線池配置 228
12.1.2 DBCP配置建議 233
12.1.3 資料庫驅動逾時實現 234
12.1.4 連線池使用的一些建議 235
12.2 HttpClient連線池 236
12.2.1 HttpClient 4.5.2配置 236
12.2.2 HttpClient連線池源碼分析 240
12.2.3 HttpClient 4.2.3配置 241
12.2.4 問題示例 243
12.3 執行緒池 244
12.3.1 Java執行緒池 245
12.3.2 Tomcat執行緒池配置 248
13 異步並發實戰 250
13.1 同步阻塞調用 251
13.2 異步Future 252
13.3 異步Callback 253
13.4 異步編排CompletableFuture 254
13.5 異步Web服務實現 257
13.6 請求快取 259
13.7 請求合併 261
14 如何擴容 266
14.1 單體套用垂直擴容 267
14.2 單體套用水平擴容 267
14.3 套用拆分 268
14.4 資料庫拆分 271
14.5 資料庫分庫分表示例 275
14.5.1 套用層還是中間件層 275
14.5.2 分庫分表策略 277
14.5.3 使用sharding-jdbc分庫分表 279
14.5.4 sharding-jdbc分庫分表配置 279
14.5.5 使用sharding-jdbc讀寫分離 283
14.6 數據異構 284
14.6.1 查詢維度異構 284
14.6.2 聚合數據異構 285
14.7 任務系統擴容 285
14.7.1 簡單任務 285
14.7.2 分散式任務 287
14.7.3 Elastic-Job簡介 287
14.7.4 Elastic-Job-Lite功能與架構 287
14.7.5 Elastic-Job-Lite示例 288
15 佇列術 295
15.1 套用場景 295
15.2 緩衝佇列 296
15.3 任務佇列 297
15.4 訊息佇列 297
15.5 請求佇列 299
15.6 數據匯流排佇列 300
15.7 混合佇列 301
15.8 其他佇列 302
15.9 Disruptor+Redis佇列 303
15.9.1 簡介 303
15.9.2 XML配置 304
15.9.3 EventWorker 305
15.9.4 EventPublishThread 307
15.9.5 EventHandler 308
15.9.6 EventQueue 308
15.10 下單系統水平可擴展架構 311
15.10.1 下單服務 313
15.10.2 同步Worker 313
15.11 基於Canal實現數據異構 314
15.11.1 Mysql主從複製 315
15.11.2 Canal簡介 316
15.11.3 Canal示例 318
第4部分案例 323
16 構建需求回響式億級商品詳情頁 324
16.1 商品詳情頁是什麼 324
16.2 商品詳情頁前端結構 325
16.3 我們的性能數據 327
16.4 單品頁流量特點 327
16.5 單品頁技術架構發展 327
16.5.1 架構1.0 328
16.5.2 架構2.0 328
16.5.3 架構3.0 330
16.6 詳情頁架構設計原則 332
16.6.1 數據閉環 332
16.6.2 數據維度化 333
16.6.3 拆分系統 334
16.6.4 Worker無狀態化+任務化 334
16.6.5 異步化+並發化 335
16.6.6 多級快取化 335
16.6.7 動態化 336
16.6.8 彈性化 336
16.6.9 降級開關 336
16.6.10 多機房多活 337
16.6.11 多種壓測方案 338
16.7 遇到的一些坑和問題 339
16.7.1 SSD性能差 339
16.7.2 鍵值存儲選型壓測 340
16.7.3 數據量大時JIMDB同步不動 342
16.7.4 切換主從 342
16.7.5 分片配置 342
16.7.6 模板元數據存儲HTML 342
16.7.7 庫存接口訪問量600w/分鐘 343
16.7.8 微信接口調用量暴增 344
16.7.9 開啟Nginx Proxy Cache性能不升反降 344
16.7.10 配送至讀服務因依賴太多,回響時間偏慢 344
16.7.11 網路抖動時,返回502錯誤 346
16.7.12 機器流量太大 346
16.8 其他 347
17 京東商品詳情頁服務閉環實踐 348
17.1 為什麼需要統一服務 348
17.2 整體架構 349
17.3 一些架構思路和總結 350
17.3.1 兩種讀服務架構模式 351
17.3.2 本地快取 352
17.3.3 多級快取 353
17.3.4 統一入口/服務閉環 354
17.4 引入Nginx接入層 354
17.4.1 數據校驗/過濾邏輯前置 354
17.4.2 快取前置 355
17.4.3 業務邏輯前置 355
17.4.4 降級開關前置 355
17.4.5 AB測試 356
17.4.6 灰度發布/流量切換 356
17.4.7 監控服務質量 356
17.4.8 限流 356
17.5 前端業務邏輯後置 356
17.6 前端接口服務端聚合 357
17.7 服務隔離 359
18 使用OpenResty開發高性能Web套用 360
18.1 OpenResty簡介 361
18.1.1 Nginx優點 361
18.1.2 Lua的優點 361
18.1.3 什麼是ngx_lua 361
18.1.4 開發環境 362
18.1.5 OpenResty生態 362
18.1.6 場景 362
18.2 基於OpenResty的常用架構模式 363
18.2.1 負載均衡 363
18.2.2 單機閉環 364
18.2.3 分散式閉環 367
18.2.4 接入網關 368
18.2.5 核心接入Nginx功能 369
18.2.6 業務Nginx功能 369
18.2.7 Web套用 370
18.3 如何使用OpenResty開發Web套用 371
18.3.1 項目搭建 371
18.3.2 啟停腳本 372
18.3.3 配置檔案 372
18.3.4 nginx.conf配置檔案 373
18.3.5 Nginx項目配置檔案 373
18.3.6 業務代碼 374
18.3.7 模板 374
18.3.8 公共Lua庫 375
18.3.9 功能開發 375
18.4 基於OpenResty的常用功能總結 375
18.5 一些問題 376
19 套用數據靜態化架構高性能單頁Web套用 377
19.1 整體架構 378
19.1.1 CMS系統 379
19.1.2 前端展示系統 380
19.1.3 控制系統 380
19.2 數據和模板動態化 381
19.3 多版本機制 381
19.4 異常問題 382
20 使用OpenResty開發Web服務 383
20.1 架構 383
20.2 單DB架構 384
20.2.1 DB+Cache/資料庫讀寫分離架構 384
20.2.2 OpenResty+Local Redis+Mysql集群架構 385
20.2.3 OpenResty+Redis集群+Mysql集群架構 386
20.3 實現 387
20.3.1 後台邏輯 388
20.3.2 前台邏輯 388
20.3.3 項目搭建 389
20.3.4 Redis+Twemproxy配置 389
20.3.5 Mysql+Atlas配置 390
20.3.6 Java+Tomcat安裝 394
20.3.7 Java+Tomcat邏輯開發 395
20.3.8 Nginx+Lua邏輯開發 401
21 使用OpenResty開發商品詳情頁 405
21.1 技術選型 407
21.2 核心流程 408
21.3 項目搭建 408
21.4 數據存儲實現 410
21.4.1 商品基本信息SSDB集群配置 410
21.4.2 商品介紹SSDB集群配置 413
21.4.3 其他信息Redis配置 417
21.4.4 集群測試 418
21.4.5 Twemproxy配置 419
21.5 動態服務實現 422
21.5.1 項目搭建 422
21.5.2 項目依賴 422
21.5.3 核心代碼 423
21.5.4 基本信息服務 424
21.5.5 商品介紹服務 426
21.5.6 其他信息服務 426
21.5.7 輔助工具 427
21.5.8 web.xml配置 428
21.5.9 打WAR包 428
21.5.10 配置Tomcat 428
21.5.11 測試 429
21.5.12 Nginx配置 429
21.5.13 綁定hosts測試 430
21.6 前端展示實現 430
21.6.1 基礎組件 430
21.6.2 商品介紹 432
21.6.4 前端展示 434
21.6.5 測試 442
21.6.6 最佳化 442