TCP连接静默断开

原文地址:https://pasztor.at/blog/tcp-connections-can-break-silently/

有一件事可能会带来很大的后果,尤其是在涉及微服务时:您的TCP连接可能会静默断开,甚至你完全不知道。

静默断开TCP连接可能导致你的微服务无限期挂起。更糟糕的是,这可能只会在生产环境中发生,我将在这篇文章中解释原因。如果你有编写微服务的经验,则可以通过在应用程序中实现断路器来解决该问题。但是,如果你刚刚开始使用微服务,那么可能需要继续阅读后面的内容。

“等一下!” -你可能会想- *“ TCP难度不是应该很可靠?” *你是对的。TCP保证任何提交的数据都能可靠地传输,否则你将收到错误消息。但是,如果你没有通过连接传输任何数据,则TCP(默认设置)不会检查连接是否仍然有效。

你也许会问,发送数据后如何进行检查?接收方每隔一段时间就向发送方发送一个确认(ack)包,以获取接收到的数据。如果在3秒钟内未收到确认,TCP重新发送数据包。如果未发送数据,则也不会发送确认。换句话说,两方之间没有数据包在传输。

//TODO ========

让我们将其应用于微服务中:服务A向服务B发送一个HTTP请求。然后服务A等待响应。在此等待期间,A或B都会不通过TCP连接发送任何数据。当服务B最终准备好处理请求时,它将把响应发送到服务A,随后连接将关闭。

到现在为止还挺好。但是,如果运行的服务B突然抛出内核异常,该怎么办?换句话说,网络链接停留在硬件级别,但是软件层面根本无法响应。在这种情况下,服务A将认为TCP连接处于活动状态,直到达到超时为止。

此超时的默认值为10分钟。服务A可能会挂起10分钟。依赖服务A的其他服务也可能会挂起同样的时间。

小心!在开发环境中,如果所有服务都在同一台计算机上运行,​​则可能看不到这种情况。在单台计算机上,如果一方崩溃,TCP连接会向你提供连接关闭错误。

所以,你可以做什么?首先,如果不需要,请不要使用微服务。我知道使用微服务是很酷的事情,但是由于中间的网络,微服务带来了更多的复杂性,而不是更少。除此之外,你还可以实现上述断路器模式,调整TCP超时并打开TCP keepalive

推荐阅读更多精彩内容