这个问题真的没有简短的答案。这是一个一般性的想法,但要回答这个问题,可能需要准确了解许多事物的工作原理以及它们如何相互作用。
首先,tbf 相当于有一个带宽设置为 tbf 的网络接口。它还设置了缓冲区大小(可以从速率和延迟计算得出)。
那么,这个队列是什么。传出接口有所谓的缓冲区。缓冲区是内存。在简单的情况下,这个内存被组织成一个队列,也就是一个称为队列(先进先出)的数据结构。如果必须在传出接口上发送数据包并且该接口正忙(发送其他数据包),则该数据包将排队,即放在队列的后面。当接口可以发送下一个数据包时,它从队列的前面取出数据包并发送它。如果一个数据包应该排队并且没有剩余内存,那么该数据包将被丢弃。
分组交换网络中的每个设备都在传出接口上使用队列。他们在那里处理临时爆发数据包的数量(即传入数据包的速率(要通过此接口发送的数据包)和接口带宽之间的短暂不匹配。这些突发是数据包交换网络的产物。如果由于某种原因,传入数据包的速率在较长时间内较高时间,这个缓冲区会在很长一段时间内变满。现在,坐在缓冲区中会增加数据包的延迟。当数据包排队时,队列越大(缓冲区越满),数据包在队列,因此延迟更高。如果缓冲区很大(以字节/它可以排队的数据包数为单位),与在从发送方到接收方的距离上传输数据包所需的延迟相比(即,不计算队列)。这被称为缓冲区膨胀。
因此,我们可以做些什么来缓解这种情况,可以粗略地分为调度程序和主动队列管理(AQM)。FQ-Codel其实两者兼有:它是FQ调度器和Codel主动队列管理方案的结合。
调度程序做什么。它以比单个队列更复杂的结构组织此缓冲存储器。让我们以来自维基百科的这张图片的底部为例。

因此,基本上不是一个队列,而是多个队列,并且数据包根据某些标准进入不同的队列(该过程通常称为分类)。例如,单个流(例如,单个 tcp 流)的数据包降落在同一个(子)队列中,但不同的流降落在不同的队列中。当传出接口可以发送下一个数据包时,调度程序决定从哪个队列中获取数据包。这是做什么的:它在队列之间分配带宽,以便每个队列获得大致相等的带宽份额,而如果一个队列不使用它的份额,它可以重新分配给其他队列。您可以阅读有关“循环”、“公平排队”、“赤字循环”和“FQ”调度程序/qdisc 的更多信息。
在下载和 ping 之间的示例中,调度程序可以确保 ping 数据包可以通过,而在它们之前到达的下载数据包仍然在排队。
现在活动队列管理方案(AQM)做什么。正如我所说,如果缓冲区中没有剩余空间,则丢弃数据包。AQM 在缓冲区变满之前丢弃一些数据包。这样做是为了让 TCP 对此数据包丢失做出反应并发送更少的数据包。目的是拥有大缓冲区,可以容纳大的短期突发,但同时保持平均队列占用率(即其中的数据包数量)低,以保持低延迟。
现在,AQM 之所以存在,是因为它们与 TCP拥塞控制交互。 拥塞控制是主机在第 4 层及更高层需要做的事情,以确保它们不会使网络过载,即它们对每个流的发送速率不会超过该流的路径的可用带宽。关于 TCP 拥塞控制和 AQM 究竟是如何交互的,没有简单的解释。TCP 拥塞控制方案TCP Reno和TCP Cubic是基于丢失的,即,他们将丢包视为他们必须做某事的指示。Reno 和 Cubic 的工作方式导致它们在实际反应之前将缓冲区填满。AQM 在队列满之前丢弃数据包,以便 TCP 可以更快地做出反应。(注意,AQM 不必丢弃数据包,它可以标记数据包 - 请参阅显式拥塞通知(ECN))。
在该问题的示例中,AQM 可用于向下载流发送信号以降低其速率。