目錄
第Ⅰ部分 云原生概述
第1 章 什么是“云原生”應用程序 11
1.1 迄今為止的故事 12
1.2 什么是云原生? 14
1.2.1 可擴展性 .15
1.2.2 松散耦合 .16
1.2.3 韌性 17
1.2.4 可管理性 .19
1.1.5 可觀察性 .20
1.3 為什么云原生很重要? .21
1.4 小結 .22
第2 章 為什么Go 語言統(tǒng)治云原生世界 23
2.1 Go 語言誕生的動機 .23
2.2 云原生世界的特性 24
2.2.1 組合與結構化類型 .25
2.2.2 可理解性 .27
2.2.3 CSP 風格的并發(fā) 27
2.2.4 快速構建 .28
2.2.5 語言穩(wěn)定性 29
2.2.6 內存安全 .30
2.2.7 性能 31
2.2.8 靜態(tài)鏈接 .32
2.2.9 靜態(tài)類型 .33
2.3 小結 .34
第Ⅱ部分 云原生Go 結構
第3 章 Go 語言基礎 39
3.1 基本數(shù)據(jù)類型 .39
3.1.1 布爾值 40
3.1.2 簡單的數(shù)字 40
3.1.3 復數(shù) 41
3.1.4 字符串 42
3.2 變量 .42
3.2.1 簡短的變量聲明 43
3.2.2 零值 44
3.2.3 空標識符 .45
3.2.4 常量 46
3.3 容器類型:數(shù)組、切片和映射 47
3.3.1 數(shù)組 .47
3.3.2 切片 48
3.3.3 映射 53
3.4 指針 .54
3.5 控制結構56
3.5.1 for 循環(huán) 56
3.5.2 if 語句 59
3.5.3 switch 語句 .60
3.6 錯誤處理62
3.7 可變參函數(shù)和閉包 63
3.7.1 函數(shù) 64
3.7.2 可變參函數(shù) 68
3.7.3 匿名函數(shù)和閉包 70
3.8 結構、方法和接口 72
3.8.1 結構 72
3.8.2 方法 73
3.8.3 接口 75
3.8.4 通過類型嵌入實現(xiàn)組合 77
3.9 并發(fā) .80
3.9.1 Go 協(xié)程 80
3.9.2 通道 80
3.9.3 select 語句 83
3.10 小結 85
第4 章 云原生模式 87
4.1 Context 包 .88
4.1.1 Context 可以做什么 89
4.1.2 創(chuàng)建Context 90
4.1.3 定義Context 的截止日期和超時 .91
4.1.4 定義請求作用域的值.91
4.1.5 使用Context 92
4.2 本章的主要內容 93
4.3 穩(wěn)定性模式 94
4.3.1 斷路器模式 94
4.3.2 防抖模式 .97
4.3.3 重試模式 102
4.3.4 節(jié)流模式 104
4.3.5 超時模式 108
4.4 并發(fā)模式. 111
4.4.1 扇入模式 112
4.4.2 扇出模式 114
4.4.3 未來模式 117
4.4.4 分片模式 122
4.5 小結 128
第5 章 構建云原生服務 129
5.1 構建一個服務! .129
5.2 需求 130
5.2.1 什么是冪等性,為什么冪等性很重要? 131
5.2.2 最終目標 133
5.3 第0 代:核心功能 .133
5.4 第一代:單體架構 .135
5.4.1 使用net/http 構建HTTP 服務器 135
5.4.2 使用gorilla/mux 構建HTTP 服務器 137
5.4.3 構建RESTful 服務 141
5.4.4 確保數(shù)據(jù)結構的并發(fā)安全 146
5.5 第2 代:持久保存資源狀態(tài) .148
5.5.1 什么是事務日志? 150
5.5.2 將狀態(tài)存儲到事務日志文件 151
5.5.3 將狀態(tài)存儲到外部數(shù)據(jù)庫 165
5.6 第3 代:實現(xiàn)傳輸層安全 .174
5.6.1 傳輸層安全 .175
5.6.2 私鑰和證書文件 176
5.6.3 使用HTTPS 保護Web 服務 177
5.6.4 傳輸層總結 .179
5.7 鍵值存儲的容器化 .179
5.7.1 Docker 的基礎知識 .181
5.7.2 構建鍵值存儲容器 188
5.7.3 外部化容器數(shù)據(jù) 193
5.8 小結 194
第Ⅲ部分 云原生屬性
第6 章 可信任性 . 197
6.1 云原生的意義 198
6.2 可信任性.198
6.3 什么是可信任性以及為什么可信任性如此重要? 199
6.4 實現(xiàn)可信任性 203
6.4.1 故障預防 205
6.4.2 容錯 .206
6.4.3 故障排除 207
6.4.4 故障預測 208
6.5 十二要素應用 209
6.5.1 基準代碼 210
6.5.2 依賴 .210
6.5.3 配置 . 211
6.5.4 依賴服務 213
6.5.5 構建、發(fā)布、運行 214
6.5.6 進程 .215
6.5.7 數(shù)據(jù)分離 216
6.5.8 可擴展性 217
6.5.9 易處理性 217
6.5.10 開發(fā)環(huán)境與生產環(huán)境等價 .218
6.5.11 日志 219
6.5.12 管理進程 219
6.6 小結 221
第7 章 可擴展性 . 223
7.1 什么是可擴展性 .225
7.2 四個常見瓶頸 226
7.3 狀態(tài)與無狀態(tài) 228
7.3.1 應用程序狀態(tài)與資源狀態(tài) 228
7.3.2 無狀態(tài)的優(yōu)勢 .229
7.4 推遲擴展:效率 .230
7.4.1 使用LRU 緩存的高效緩存 .231
7.4.2 高效同步 234
7.4.3 內存泄漏可能會致命錯誤:運行時:內存不足 .240
7.4.4 高效 .244
7.5 服務架構.244
7.5.1 單體系統(tǒng)架構 .245
7.5.2 微服務系統(tǒng)架構 246
7.5.3 無服務器架構 .248
7.6 小結 253
第8 章 松散耦合 . 255
8.1 緊密耦合.256
8.2 服務之間的通信 .260
8.3 請求響應消息 261
8.3.1 常見的請求響應實現(xiàn)262
8.3.2 通過net/http 發(fā)送HTTP 請求 263
8.3.3 使用gRPC 實現(xiàn)遠程過程調用 267
8.4 利用插件實現(xiàn)本地資源的松散耦合280
8.4.1 帶有插件包的進程內插件 281
8.4.2 基于RPC 的HashiCorp 插件系統(tǒng) 288
8.5 六邊形架構 297
8.5.1 架構 .297
8.5.2 實現(xiàn)六邊形服務 299
8.6 小結 307
第9 章 韌性 . 309
9.1 為什么韌性很重要 .310
9.2 系統(tǒng)失效是什么意思? 311
9.3 級聯(lián)失效.313
9.4 重試請求.321
9.4.1 退避算法 322
9.4.2 斷路器 325
9.4.3 超時 .327
9.4.4 冪等性 333
9.5 服務冗余.337
9.5.1 設計系統(tǒng)時考慮冗余338
9.5.2 自動擴展 340
9.6 健康檢查.341
9.6.1“健康的”實例意味著什么? .342
9.6.2 三種類型的健康檢查343
9.6.3 故障打開 348
9.7 小結 348
第10 章 可管理性 351
10.1 什么是可管理性,為什么我應該關注可管理性? 352
10.2 配置應用程序 354
10.2.1 有關配置的良好實踐 355
10.2.2 環(huán)境變量配置 355
10.2.3 命令行參數(shù)配置 .357
10.2.4 配置文件 363
10.2.5 Viper:配置包中的瑞士軍刀 381
10.3 利用特性標志管理功能 386
10.3.1 特性標志的進化 .387
10.3.2 第零代:最初的實現(xiàn) 388
10.3.3 第一代:硬編碼特性標志 .388
10.3.4 第二代:可配置標志 390
10.3.5 第三代:動態(tài)特性標志 391
10.4 小結 395
第11 章 可觀察性 397
11.1 什么是可觀察性? 398
11.1.1 為什么我們需要可觀察性? .399
11.1.2 可觀察性與“傳統(tǒng)的”監(jiān)控有何不同? 399
11.2 “可觀察性的三大支柱” 400
11.3 OpenTelemetry 402
11.4 追蹤 404
11.4.1 追蹤的概念 405
11.4.2 使用OpenTelemetry 進行追蹤 407
11.4.3 整合:追蹤 420
11.5 指標 427
11.5.1 推式與拉式指標集合 429
11.5.2 OpenTelemetry 的指標 432
11.5.3 整合:指標 444
11.6 日志記錄 447
11.6.1 更好的日志記錄實踐 448
11.6.2 使用Go 標準的log 包記錄日志 .452
11.6.3 Zap 日志包 455
11.7 小結 462