本書通過拋出了一些開發、運維等技術人員工作中的常見問題,激發讀者的思考。從這些疑問出發,深入地對網絡底層實現原理進行了拆解,帶領讀者看清楚問題的核心,提高大家的技術功力。例如網絡包是如何被接收和發送的?阻塞到底在內部是如何發生的?epoll 的底層工作原理又是啥?TCP 連接在底層上是如何支持和實現的?書中對這些內容都有深度的闡述。本書旨在通過帶領讀者修煉底層內功,進而幫助大家深度掌握網絡高性能原理。
張彥飛,2010年碩士畢業于西北大學計算機學院,有十多年的大型互聯網公司項目經驗,目前就職于騰訊。他喜歡對技術進行深度思考,善于挖掘技術點背后的原理。他的技術公眾號“開發內功修煉”一年便收到五萬多讀者的關注。
第1章 緒論 / 1
1.1 我在工作中的困惑 / 2
1.1.1 過多的TIME_WAIT / 2
1.1.2 長連接開銷 / 2
1.1.3 CPU被消耗光了 / 3
1.1.4 為什么不同的語言網絡性能差別巨大 / 4
1.1.5 訪問127.0.0.1過網卡嗎 / 4
1.1.6 軟中斷和硬中斷 / 5
1.1.7 零拷貝到底是怎么回事 / 5
1.1.8 DPDK / 5
1.2 本書內容結構 / 6
1.3 一些約定 / 7
1.4 一些術語 / 8
第2章 內核是如何接收網絡包的 / 9
2.1 相關實際問題 / 10
2.2 數據是如何從網卡到協議棧的 / 11
2.2.1 Linux網絡收包總覽 / 12
2.2.2 Linux啟動 / 13
2.2.3 迎接數據的到來 / 23
2.2.4 收包小結 / 33
2.3 本章總結 / 34
第3章 內核是如何與用戶進程協作的 / 41
3.1 相關實際問題 / 42
3.2 socket的直接創建 / 43
3.3 內核和用戶進程協作之阻塞方式 / 46
3.3.1 等待接收消息 / 47
3.3.2 軟中斷模塊 / 52
3.3.3 同步阻塞總結 / 57
3.4 內核和用戶進程協作之epoll / 59
3.4.1 epoll內核對象的創建 / 60
3.4.2 為epoll添加socket / 62
3.4.3 epoll_wait之等待接收 / 68
3.4.4 數據來了 / 71
3.4.5 小結 / 79
3.5 本章總結 / 80
第4章 內核是如何發送網絡包的 / 84
4.1 相關實際問題 / 85
4.2 網絡包發送過程總覽 / 86
4.3 網卡啟動準備 / 90
4.4 數據從用戶進程到網卡的詳細過程 / 92
4.4.1 send系統調用實現 / 92
4.4.2 傳輸層處理 / 94
4.4.3 網絡層發送處理 / 99
4.4.4 鄰居子系統 / 103
4.4.5 網絡設備子系統 / 105
4.4.6 軟中斷調度 / 109
4.4.7 igb網卡驅動發送 / 111
4.5 RingBuffer內存回收 / 114
4.6 本章總結 / 115
第5章 深度理解本機網絡IO / 119
5.1 相關實際問題 / 120
5.2 跨機網絡通信過程 / 120
5.2.1 跨機數據發送 / 120
5.2.2 跨機數據接收 / 125
5.2.3 跨機網絡通信匯總 / 127
5.3 本機發送過程 / 127
5.3.1 網絡層路由 / 127
5.3.2 本機IP路由 / 130
5.3.3 網絡設備子系統 / 131
5.3.4 “驅動”程序 / 133
5.4 本機接收過程 / 135
5.5 本章總結 / 137
第6章 深度理解TCP連接建立過程 / 139
6.1 相關實際問題 / 140
6.2 深入理解listen / 141
6.2.1 listen系統調用 / 141
6.2.2 協議棧listen / 142
6.2.3 接收隊列定義 / 143
6.2.4 接收隊列申請和初始化 / 145
6.2.5 半連接隊列長度計算 / 146
6.2.6 listen過程小結 / 148
6.3 深入理解connect / 148
6.3.1 connect調用鏈展開 / 149
6.3.2 選擇可用端口 / 151
6.3.3 端口被使用過怎么辦 / 153
6.3.4 發起syn請求 / 155
6.3.5 connect小結 / 156
6.4 完整TCP連接建立過程 / 157
6.4.1 客戶端connect / 159
6.4.2 服務端響應SYN / 160
6.4.3 客戶端響應SYNACK / 162
6.4.4 服務端響應ACK / 164
6.4.5 服務端accept / 167
6.4.6 連接建立過程總結 / 167
6.5 異常TCP連接建立情況 / 169
6.5.1 connect系統調用耗時失控 / 169
6.5.2 第一次握手丟包 / 171
6.5.3 第三次握手丟包 / 176
6.5.4 握手異?偨Y / 178
6.6 如何查看是否有連接隊列溢出發生 / 179
6.6.1 全連接隊列溢出判斷 / 179
6.6.2 半連接隊列溢出判斷 / 181
6.6.3 小結 / 183
6.7 本章總結 / 183
第7章 一條TCP連接消耗多大內存 / 187
7.1 相關實際問題 / 188
7.2 Linux內核如何管理內存 / 188
7.2.1 node劃分 / 189
7.2.2 zone劃分 / 191
7.2.3 基于伙伴系統管理空閑頁面 / 192
7.2.4 slab分配器 / 194
7.2.5 小結 / 197
7.3 TCP連接相關內核對象 / 198
7.3.1 socket函數直接創建 / 198
7.3.2 服務端socket創建 / 206
7.4 實測TCP內核對象開銷 / 207
7.4.1 實驗準備 / 207
7.4.2 實驗開始 / 208
7.4.3 觀察ESTABLISH狀態開銷 / 209
7.4.4 觀察非ESTABLISH狀態開銷 / 211
7.4.5 收發緩存區簡單測試 / 214
7.4.6 實驗結果小結 / 215
7.5 本章總結 / 216
第8章 一臺機器最多能支持多少條TCP連接 / 218
8.1 相關實際問題 / 219
8.2 理解Linux最大文件描述符限制 / 219
8.2.1 找到源碼入口 / 220
8.2.2 尋找進程級限制nofile和fs.nr_open / 221
8.2.3 尋找系統級限制fs.file-max / 223
8.2.4 小結 / 224
8.3 一臺服務端機器最多可以支撐多少條TCP連接 / 225
8.3.1 一次關于服務端并發的聊天 / 225
8.3.2 服務器百萬連接達成記 / 228
8.3.3 小結 / 232
8.4 一臺客戶端機器最多只能發起65 535條連接嗎 / 232
8.4.1 65 535的束縛 / 232
8.4.2 多IP增加連接數 / 234
8.4.3 端口復用增加連接數 / 236
8.4.4 小結 / 243
8.5 單機百萬并發連接的動手實驗 / 243
8.5.1 方案一,多IP客戶端發起百萬連接 / 244
8.5.2 方案二,單IP客戶端機器發起百萬連接 / 248
8.5.3 最后多談一點 / 250
8.6 本章總結 / 251
第9章 網絡性能優化建議 / 253
9.1 網絡請求優化 / 254
9.2 接收過程優化 / 256
9.3 發送過程優化 / 262
9.4 內核與進程協作優化 / 268
9.5 握手揮手過程優化 / 269
第10章 容器網絡虛擬化 / 272
10.1 相關實際問題 / 273
10.2 veth設備對 / 274
10.2.1 veth如何使用 / 274
10.2.2 veth底層創建過程 / 276
10.2.3 veth網絡通信過程 / 278
10.2.4 小結 / 281
10.3 網絡命名空間 / 281
10.3.1 如何使用網絡命名空間 / 282
10.3.2 命名空間相關的定義 / 284
10.3.3 網絡命名空間的創建 / 287
10.3.4 網絡收發如何使用網絡命名空間 / 295
10.3.5 結論 / 296
10.4 虛擬交換機Bridge / 297
10.4.1 如何使用Bridge / 298
10.4.2 Bridge是如何創建出來的 / 301
10.4.3 添加設備 / 303
10.4.4 數據包處理過程 / 305
10.4.5 小結 / 308
10.5 外部網絡通信 / 310
10.5.1 路由和NAT / 311
10.5.2 實現外部網絡通信 / 313
10.5.3 小結 / 318
10.6 本章總結 / 319