在webservices的上下文中,我已经看到使用术语“TCP连接流失”。具体来说,Twitter finagle有办法避免它发生。怎么会发生?这是什么意思?
答案 0 :(得分:8)
这个术语可能有多种用途,但我总是看到它用于在很短的时间内制作许多TCP连接的情况,从而导致客户端和服务器上的性能问题。
这通常发生在编写客户端代码时,它会自动连接任何类型的TCP故障。如果在连接成功之前(或者在协议交换的早期阶段)发生连接失败,那么客户端可以进入一个接近忙碌的循环,不断建立连接。这可能会导致客户端出现性能问题 - 首先是在一个非常繁忙的循环中有一个进程吸收CPU周期,其次是每个连接尝试都消耗一个客户端端口号 - 如果这个速度足够快,软件可以回绕当他们达到最大端口号时(因为端口只有16位数,这当然不是不可能)。
虽然编写健壮的代码是一个有价值的目标,但这种简单的“自动重试”方法有点过于幼稚。你可以在其他环境中看到类似的问题 - 例如父进程不断重新启动立即崩溃的子进程。避免它的一种常见机制是某种增加的退缩。因此,当第一个连接失败时,您立即重新连接。如果它在短时间内(例如30秒)再次失败,那么在重新连接之前等待,比如2秒。如果它在30秒内再次失败,则等待4秒,依此类推。阅读the Wikipedia article on exponential backoff(或this blog post可能更适合此应用程序)以获取有关此技术的更多背景信息。
这种方法的优点是它不会压倒客户端或服务器,但它也意味着客户端仍然可以在没有人工干预的情况下恢复(这对于无人值守服务器上的软件尤为重要,例如,在大型集群中)。
在恢复时间至关重要的情况下,TCP连接创建的简单速率限制也很可能 - 可能每秒不超过1次。但是,如果每台服务器上有许多客户端,这种更简单的方法仍然会使服务器因接受负载然后关闭高连接速率而淹没。
如果您打算采用指数退避,有一点需要注意 - 我建议施加最长等待时间,或者您可能会发现,一旦服务器端再次开始接受连接,长时间的故障会导致客户端花费太长时间才能恢复。在大多数情况下,我建议将5分钟作为合理的最大值,但当然这取决于应用程序。