内容简介
· · · · · ·
《程序员进阶之路:缓存、网络、内存与案例》主要讲解计算机系统中核心的技术知识,涵盖缓存、内存屏障、无锁编程、网络基础、TCP/UDP、端口复用、网络收发包流程、物理内存、虚拟内存等内容。本书还分享了实际工作中可能出现的技术难题及解决方案供读者借鉴。
为了使读者轻松、快速地理解书中晦涩难懂的技术知识,本书作者精心绘制了大量的流程图、结构图。为了使读者更好地理解Linux内核源码,本书还提供了大量经过注释的Linux内核源码供读者下载。
通过阅读本书,读者可以轻松、快速地掌握这些技术知识,并通过源码和书中配图加强对相关知识的理解。
作者简介
· · · · · ·
邓中华,高级软件工程师。拥有5年互联网服务端开发经验和6年游戏服务端开发经验。曾就职于搜狐畅游,负责大型游戏服务端开发。曾多次担任“救火队长”主导分析并解决线上重大事故,累计为公司减少经济损失达千万级别。擅长服务端架构设计,以及性能、网络和内存的优化
目录
· · · · · ·
第1章 缓存 1
1.1 存储体系结构 1
1.2 缓存一致性协议 4
1.2.1 MESI协议 4
1.2.2 MOESI协议 8
1.2.3 MESIF协议 9
1.3 写缓存区和无效队列 9
1.3.1 写缓冲区的作用 11
1.3.2 无效队列的作用 11
1.4 内存屏障 11
1.4.1 读写屏障 12
1.4.2 单向屏障 12
1.5 x86-TSO 13
1.6 CPU黑盒测试 15
1.6.1 测试核心内是否存在Store Buffer 15
1.6.2 测试转发(Store Forwarding)是否生效 17
1.6.3 测试StoreStore是否乱序执行 18
1.6.4 测试LoadLoad是否乱序执行 19
1.6.5 测试LoadStore是否乱序执行 19
1.6.6 测试StoreLoad是否乱序执行 20
1.7 CAS原理 20
1.8 原子操作 22
1.8.1 互斥锁 23
1.8.2 自旋锁 23
1.8.3 C++原子变量 25
1.8.4 C++内存顺序 26
1.9 无锁队列 31
1.9.1 设计思路 31
1.9.2 实现细节 32
第2章 网络 36
2.1 网络分层 36
2.2 网络接口层(以太网) 37
2.3 网络层(IP、ICMP) 39
2.3.1 IP 39
2.3.2 ICMP 43
2.4 套接字编程 47
2.4.1 套接字 47
2.4.2 函数 47
2.4.3 多路复用 49
2.5 虚拟网卡 54
2.5.1 Tun设备 54
2.5.2 创建代码 55
2.6 网络抓包 56
2.6.1 tcpdump 56
2.6.2 Wireshark 59
2.7 网络工具 61
2.7.1 ethtool工具 61
2.7.2 ifconfig工具 65
2.7.3 ip工具 66
2.7.4 nc工具 66
2.8 网卡的特性(Feature) 67
2.8.1 LRO 67
2.8.2 GRO 67
2.8.3 TSO 68
2.8.4 GSO 68
2.9 网络栈的扩展(Scaling) 69
2.9.1 RSS 69
2.9.2 RPS 71
2.9.3 RFS 72
2.9.4 XPS 73
2.10 硬中断的负载均衡 74
2.10.1 硬中断的CPU亲和性 74
2.10.2 irqbalance功能 75
第3章 TCP 76
3.1 协议体 76
3.2 有限状态机 81
3.2.1 netstat 82
3.2.2 ss 82
3.3 准备阶段 83
3.4 握手阶段 84
3.4.1 三次握手 84
3.4.2 初始化序列号 88
3.5 连接阶段 89
3.5.1 重传机制 90
3.5.2 确认机制 93
3.5.3 乱序恢复机制 94
3.5.4 保活机制 95
3.6 流量控制 97
3.6.1 滑动窗口 97
3.6.2 流量控制过程 99
3.6.3 零窗口 100
3.7 拥塞控制 101
3.7.1 拥塞控制算法 101
3.7.2 CUBIC 102
3.8 挥手阶段 109
3.8.1 四次挥手 109
3.8.2 三次挥手 112
3.8.3 同时挥手 113
3.8.4 关闭函数 114
第4章 UDP 117
4.1 协议体 117
4.2 特点 119
4.2.1 无连接性 119
4.2.2 不可靠性 122
4.2.3 面向报文 122
4.2.4 最大交付 124
4.2.5 最小开销 125
4.3 应用场景 125
4.4 可靠性保障 126
4.4.1 ACK 126
4.4.2 FEC 126
第5章 端口 128
5.1 问题 128
5.2 地址和端口复用的总结 128
5.2.1 两个选项均关闭 129
5.2.2 仅开启一个选项 129
5.2.3 仅开启地址复用选项 130
5.2.4 开启端口复用选项 131
5.3 地址复用的应用场景 132
5.4 端口复用的应用场景 133
5.4.1 单工作线程 133
5.4.2 多工作线程 137
5.5 TCP和UDP绑定同一端口 138
第6章 收包 139
6.1 网卡的准备过程 139
6.1.1 网卡驱动的加载 140
6.1.2 网卡驱动的初始化 141
6.1.3 启用网卡 143
6.2 收包过程总览 145
6.3 网络接口层 148
6.3.1 网卡收到数据包 149
6.3.2 内核收到硬中断 149
6.3.3 内核收到软中断 150
6.3.4 清理接收队列 152
6.3.5 GRO 158
6.3.6 RPS 159
6.3.7 数据包进入协议栈之前 161
6.4 网络层(IP) 168
6.4.1 网络协议栈入口 169
6.4.2 数据包的流向 171
6.4.3 数据包的转发 172
6.4.4 数据包进入传输层之前 173
6.5 传输层(UDP) 174
6.5.1 UDP协议入口 175
6.5.2 数据包的特殊处理 176
6.5.3 将数据包放入接收队列 178
6.5.4 唤醒等待数据的进程/线程 179
6.6 套接字层 183
6.6.1 创建套接字 183
6.6.2 绑定套接字 188
6.6.3 读取套接字 189
第7章 发包 195
7.1 发包流程总览 195
7.2 套接字层 198
7.2.1 send/sendto函数(用户态) 198
7.2.2 send/sendto系统调用(内核态) 199
7.2.3 选择发送函数 200
7.2.4 将消息对象递交到传输层 201
7.3 传输层(UDP) 202
7.3.1 处理消息对象 203
7.3.2 处理数据包(struct sk_buff) 211
7.4 网络层(IP) 212
7.4.1 IP层入口函数 213
7.4.2 IPv4的发送函数 214
7.4.3 执行BPF程序 214
7.4.4 数据包的分片 215
7.4.5 将数据包发给邻居子系统 216
7.5 邻居子系统 217
7.5.1 确定发送路径 219
7.5.2 快速发送路径 220
7.5.3 慢速发送路径 222
7.6 网络接口层 225
7.6.1 网络接口层入口 226
7.6.2 内核选择发送队列 229
7.6.3 运行排队规则 233
7.6.4 将数据包递交到网卡驱动 235
7.6.5 网卡驱动发包 236
7.6.6 软中断处理过程 240
7.6.7 网卡发送完成 241
第8章 内存 244
8.1 物理内存 244
8.1.1 物理内存模型 244
8.1.2 物理内存架构 250
8.1.3 物理内存节点 253
8.1.4 物理内存区域 256
8.1.5 物理内存页 261
8.1.6 物理内存布局 266
8.1.7 物理内存硬件 269
8.2 虚拟内存 270
8.2.1 虚拟内存布局 270
8.2.2 虚拟内存空间 279
8.2.3 虚拟内存区域 288
8.2.4 虚拟内存申请 290
8.3 内存映射 301
8.3.1 正向映射 301
8.3.2 反向映射 307
第9章 案例 310
9.1 伪内存泄漏排查 310
9.1.1 背景 310
9.1.2 分析 310
9.1.3 定位 311
9.2 周期性事故处理 312
9.2.1 背景 312
9.2.2 猜想(大胆假设) 312
9.2.3 定位(小心求证) 313
9.2.4 总结 316
· · · · · ·