8

在 Web 服务的上下文中,我看到使用了术语“TCP 连接搅动”。具体来说, Twitter finagle有办法避免它发生。它是如何发生的?这是什么意思?

4

1 回答 1

9

这个术语可能有多种用途,但我总是看到它用于在很短的时间内建立许多 TCP 连接的情况,这会导致客户端和服务器的性能问题。

这通常发生在编写客户端代码时,该代码会在任何类型的 TCP 故障时自动连接。如果此失败恰好是在连接建立之前(或在协议交换的早期)发生的连接失败,那么客户端可以进入一个近乎忙碌的循环,不断地建立连接。这可能会导致客户端的性能问题——首先,在一个非常繁忙的循环中有一个进程会占用 CPU 周期,其次,每次连接尝试都会消耗一个客户端端口号——如果速度足够快,软件可以环绕当它们达到最大端口号时(因为端口只有 16 位数字,这当然不是不可能的)。

虽然编写健壮的代码是一个有价值的目标,但这种简单的“自动重试”方法有点太天真了。您可以在其他上下文中看到类似的问题 - 例如,父进程不断重新启动子进程,该子进程立即崩溃。避免它的一种常见机制是某种增加的回退。因此,当第一次连接失败时,您会立即重新连接。如果它在很短的时间内(例如 30 秒)再次失败,那么您在重新连接之前等待,比如说,2 秒。如果在 30 秒内再次失败,则等待 4 秒,以此类推。阅读有关指数退避的 Wikipedia 文章(或此博客文章可能更适合此应用程序)以了解有关此技术的更多背景信息。

这种方法的优点是它不会压倒客户端或服务器,但这也意味着客户端仍然可以在没有人工干预的情况下恢复(这对于无人值守服务器上的软件或大型集群中的软件尤其重要)。

在恢复时间很关键的情况下,TCP 连接创建的简单速率限制也是很可能的——可能不超过每秒 1 次或其他什么。但是,如果每台服务器有很多客户端,这种更简单的方法仍然会使服务器被接受然后关闭高连接率的负载所淹没。

如果您计划使用指数退避,需要注意的一件事 - 我建议设置最大等待时间,或者您可能会发现,一旦服务器端确实开始再次接受连接,长时间的故障会使客户端需要很长时间才能恢复。在大多数情况下,我建议将 5 分钟作为合理的最大值,但这当然取决于应用程序。

于 2013-02-03T10:43:13.197 回答