Docker 服务在一段时间后停止通信

2024-02-14

我有 6 个容器在 docker swarm 中运行。 Kafka+Zookeeper、MongoDB、A、B、C 和接口。 Interface 是公共的主要访问点 - 只有此容器发布端口 - 5683。 Interface 容器在启动期间连接到 A、B 和 C。我正在使用 docker-compose 文件 + docker stack 部署,每个服务都有一个名称,用作接口的主机。一切都开始成功并且工作正常。一段时间后(20 分钟,1 小时,..)我无法向界面发出请求。接口收到我的请求,但应用程序失去了与服务 A、B、C 或所有服务的连接。如果我重新启动接口,它能够重新连接到服务 A、B、C。

我首先认为这是应用程序的问题,因此我在每个服务上公开了 2 个新端口(接口、A、B、C),并使用探查器和调试器连接到它们。应用程序运行正常,无泄漏,无阻塞线程,正常工作并等待连接。调试器向我显示,当我向接口发出请求并且接口尝试请求服务 A 时,抛出了对等异常连接重置。

在这次调试过程中我发现了一些有趣的东西。当服务启动时,我将调试器附加到接口,并且调试器在一段时间后断开连接。 + 在我向容器 -> 应用程序发出请求之前,我无法重新连接它。问题 - 握手失败。

我发现的另一个有趣的事情是我无法请求这两个接口。所以我使用wireshark来查看发生了什么并且:SYN - ACK 很好。然后应用程序发布一些数据并通过 FIN、ACK 接口进行响应。我假设当接口尝试请求服务 A 并且它 FIN 连接时也会发生这种情况。对于 netty 服务器,接口、A、B 和 C 的代码库是相同的。

最后,我认为这不是应用程序的问题。为什么?我尝试将容器部署为服务而不是部署容器。我单独运行每个容器,发布每个容器的端口,并将服务端点设置为本地主机。 (不是覆盖网络)。它正在发挥作用。容器运行没有问题。 + 我一开始并没有说,java 应用程序(接口、A、B、C)在作为独立应用程序运行时运行没有问题 - 而不是在 docker 中。

您能帮我看看可能是什么问题吗?为什么在覆盖网络的情况下docker会关闭套接字?

我正在使用最新的码头工人。我用的也比较旧。


最后,我能够解决这个问题。

又发生了什么事。接口打开与 A、B、C 的永久 TCP 连接。当您尝试将这些服务 A、B、C 作为独立的 java 应用程序运行时,一切正常。当我们对它们进行 docker 化并在群中运行时,它只工作了几分钟。奇怪的是,当您从客户端向接口发出请求时,接口与另一个服务之间的连接就中断了。

经过多次不成功的测试和调试每个容器后,我尝试使用映射端口单独运行每个 docker 容器,并将 localhost 指定为端点。 (每个容器暴露的端口和接口都连接到本地主机)有趣的事情发生了,它正在工作。当您像这样运行容器时,会使用不同的容器网络驱动程序。桥一。如果您在 swarm 中运行它,则使用覆盖网络驱动程序。

所以它必须与 docker 网络有关,而不是与应用程序本身有关。下一步是几分钟后从每个容器中进行 tcpdump,此时它应该停止工作。它很有意思。

  • 客户端 -> 接口(好的,请求已接受)
  • Interface ->(forward request because it belongs to A) A
    • 界面 -> A [POST]
    • A -> 接口 [重置]

几分钟后没有通信,A 正在重置打开的 TCP 通信。为什么?

Docker使用IP Virtual Server,IPVS维护自己的连接表。 IPVS 表中 CLOSE_WAIT 连接的默认超时为 60 秒。因此,当服务器在 60 秒后发送某些内容时,IPVS 连接不再可用,并且数据包对于新的 TCP 会话看起来无效并获取 RST。在客户端,连接永远保持在 FIN_WAIT2 状态,因为应用程序仍然打开套接字;内核的 fin_wait 计时器仅针对孤立的 TCP 套接字启动。

这就是我读到的内容以及如何理解它。我不确定我对问题的解释是否正确,但基于这些假设,我在接口和 A、B、C 服务之间实现了乒乓球,以防

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Docker 服务在一段时间后停止通信 的相关文章

随机推荐