写在前面

TCP 数据的发送与接收是个很大的话题,拖了很久也想不到好的切入点。这部分可以简单分为「超时重传」「窗口管理」以及「拥塞控制」三个主要部分。掉书袋的话恐怕会让这篇文章被束之高阁(每写一道数学公式就会失去一半读者),所以这篇文档对具体算法只谈思想不谈公式,然后佐以代码或命令来验证实现细节。

TCP 超时重传

理解 TCP,就是理解如何在一个会出现信息丢失、重复、乱序的底层通信媒介上,设计一组交互协议来可靠保序地传递信息,同时还要兼顾传输的性能和稳定性。上篇提到 TCP 是基于自动重复请求的机制(Automatic Repeat Request, ARQ)来设计的。简单说就是对待发送的数据(Payload)进行字节级别的编号(Sequence Number)。在 TCP 完成三次握手建立了连接后(在不携带数据的包里,握手的 SYN 包和挥手的 FIN 也要占用编号),发送的数据均带有相应的位置序号。接收端可以根据序号对数据进行重排序来解决传输过载中存在的乱序送达的情况,并回复 ACK 包给发送端以告知数据送达(不需要请求回复一对一,只需要 ACK 最大的位置即可)。基于这个朴素的数据编号的想法,TCP 完成了发送和接收数据的基本逻辑。

Read More

写在前面

通信媒介可能会丢失或者改变被传递的消息,在这类有损通信信道上提供可靠通信协议的问题已经被研究了很多年。处理差错的两种主要方法是纠错码数据重传。后者又称之为自动重复请求(Automatic Repeat Request, ARQ),TCP 协议基于此方法设计。

本文不会完全阐述 TCP 协议的概念细节,更多的是以实验的方式揭示 TCP 在 Linux 内核协议栈上的实现细节。所以实践本文前需要先行阅读计算机网络基础以及 TCP/IP 协议相关的理论书籍。TCP 的原始规范是 RFC793,其中的一些错误在 RFC1122 中被修正。拥塞控制(RFC5681RFC3782/RFC6582RFC3517/RFC6657RFC3390RFC3168/RFC8311)、重传超时(RFC6298RFC5682RFC4015)、连接管理(RFC5482)等特性在后续一系列的 RFC 文档中也进行了补充设计。

本文在阐述一些具体的行为和特性时也会提示相关的 RFC 文档。但是需要注意,具体系统的协议实现并非完全照搬 RFC 的每一句话,实践中在一些特定的场景下也会选择更有利于解决具体问题的方案。

Read More

写在前面

本文需要读者熟悉 Ethernet(以太网)的基本原理和 Linux 系统的基本网络命令,以及 TCP/IP 协议族并了解传统的网络模型和协议包的流转原理。文中涉及到 Linux 内核的具体实现时,均以内核 v4.19.215 版本为准。

内核网络包接收流程

从网卡到内核协议栈

Read More

写在前面

本文主要分析 Linux 系统内存统计的一些指标以及进程角度内存使用监控的一些方法。

开始阅读这篇文章前,请先简单阅读下面的几篇文章。

想必这几篇文章过后,基本概念就不需要再赘述了。所以下文直接就找一台 Intel x86_64 架构下安装了 64bit Linux 系统的服务器作为例进行相关的实验和结果分析。Linux 的内存管理从物理内存管理到虚拟内存管理涉及的概念和统计项实在太多,本文从实用和系统运维的角度出发,只列举一些最实用的统计。

Read More