在 Azure 上的 Docker 容器内运行时,Maven 构建下载工件连接缓慢/重置

2024-01-04

我们有一个 docker 映像,它为特定存储库运行 git clone 命令,然后运行 ​​maven build 。在本地运行此图像时,它工作正常。在 AWS VM 中运行此映像时,它运行良好。

我们遇到的问题是,当我们在 ACI(Azure 容器实例)或 Azure VM 中运行此映像时 - maven 构建中的下载工件步骤存在一些连接问题 - jar 下载速度非常慢(有时) - 并且甚至超时(有时)。

我们参数化使用此映像构建的存储库 - 并且超时问题仅发生在少数项目上。据我们所知,这些项目没有什么特别的。

对于我们实际运行的 vm 和 mvn 命令的特定配置 - 连接问题发生在同一组工件上。

如果我们更改 mvn 命令 - 发生连接问题的位置会发生变化。

  1. 最初我们有一个mvn clean package在 git clone 之后执行的命令 - 在一组特定的 jar 上生成问题。 然后我们添加了mvn dependency:resolve-plugins, mvn compile dependency:resolve最后mvn clean package。 我们这样做是因为我们认为最初运行的一些测试可能会导致连接问题 - 因此我们首先移动了工件下载步骤。这并没有解决问题 - 只是改变了 jar 下载冻结的位置。

  2. 更改了 mvn 线程计数配置以及 VM 核心和内存大小 - 但这没有帮助。

  3. 我们在 VM 上设置了 TCP Keepalive 标志 - 以避免可能的 Azure NAT/负载均衡器超时导致我们的连接中断。 这是 Azure 支持建议的解决方案,我们也在此处找到了它:下载工件时 Maven 构建会重置连接 https://stackoverflow.com/questions/42024619/maven-build-gets-connection-reset-when-downloading-artifacts我们根据azure的guide进行配置:https://github.com/wbuchwalter/azure-content/blob/master/includes/guidance-tcp-session-timeout-include.md https://github.com/wbuchwalter/azure-content/blob/master/includes/guidance-tcp-session-timeout-include.md

> sysctl net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_intvl net.ipv4.tcp_keepalive_probes
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 20

这是 mvn 日志的示例:

14:10:48,505 [BasicRepositoryConnector-repo.maven.apache.org-27-0] [INFO] Downloading from central: https://repo.maven.apache.org/maven2/regexp/regexp/1.3/regexp-1.3.jar
14:10:48,506 [BasicRepositoryConnector-repo.maven.apache.org-27-2] [INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/scm/maven-scm-provider-cvs-commons/1.7/maven-scm-provider-cvs-commons-1.7.jar
14:10:48,505 [BasicRepositoryConnector-repo.maven.apache.org-27-1] [INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/scm/maven-scm-provider-git-commons/1.7/maven-scm-provider-git-commons-1.7.jar
14:10:48,521 [BasicRepositoryConnector-repo.maven.apache.org-27-3] [INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/tmatesoft/sqljet/sqljet/1.0.4/sqljet-1.0.4.jar
14:10:48,523 [BasicRepositoryConnector-repo.maven.apache.org-27-4] [INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/antlr/antlr-runtime/3.1.3/antlr-runtime-3.1.3.jar
14:10:48,540 [BasicRepositoryConnector-repo.maven.apache.org-27-0] [INFO] Downloaded from central: https://repo.maven.apache.org/maven2/regexp/regexp/1.3/regexp-1.3.jar (25 kB at 706 kB/s)
14:10:48,540 [BasicRepositoryConnector-repo.maven.apache.org-27-0] [INFO] Downloading from central: https://repo.maven.apache.org/maven2/org/antlr/stringtemplate/3.2/stringtemplate-3.2.jar
14:10:48,564 [BasicRepositoryConnector-repo.maven.apache.org-27-0] [INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/antlr/stringtemplate/3.2/stringtemplate-3.2.jar (172 kB at 4.0 MB/s)
14:26:32,150 [BasicRepositoryConnector-repo.maven.apache.org-27-2] [INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/scm/maven-scm-provider-cvs-commons/1.7/maven-scm-provider-cvs-commons-1.7.jar (80 kB at 84 B/s)
14:26:32,157 [BasicRepositoryConnector-repo.maven.apache.org-27-4] [INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/antlr/antlr-runtime/3.1.3/antlr-runtime-3.1.3.jar (151 kB at 159 B/s)
14:26:32,199 [BasicRepositoryConnector-repo.maven.apache.org-27-3] [INFO] Downloaded from central: https://repo.maven.apache.org/maven2/org/tmatesoft/sqljet/sqljet/1.0.4/sqljet-1.0.4.jar (744 kB at 788 B/s)

注意可疑之处:(159 B/s 时为 151 kB)、(84 B/s 时为 80 kB)、(788 B/s 时为 744 kB)

我们有运行良好的执行示例 - 以及超时(1 小时)的执行示例 - 以及花费接近 1 小时的执行示例。

解决方案:

  • 我们可以选择在初始 docker 映像中预先缓存一些 jar,因此不需要 Maven 来处理它们。但是处理此构建的 docker 映像需要为任何 git 存储库(Java + Maven)运行,并且我们无法知道这些项目有哪些依赖项。

  • 与另一点类似,可以选择创建在运行的容器之间共享的外部卷并在那里缓存 jar。

  • 一旦失败,我们可以选择重新启动 Maven 构建 - 因为部分依赖项已经下载,并且不会卡在同一个地方。

我们联系了 Azure 支持,他们推荐了 TCP Keep-alive 配置 - 但这并没有解决我们的问题。

我们想了解问题的根本原因 - 是 docker 配置吗?这是一个 Maven 错误吗?这是一个天蓝色的具体问题吗? 连接问题大约发生在 9/10 次执行中 - 我不知道为什么它有效 - 也不知道为什么它不起作用:) 我之前提到的解决方案只是解决方法 - 它们不能修复它 - 只是忽略它。

发现问题了

问题是 Maven 重用相同的 HTTP 连接来下载 pom/jar 文件。https://maven.apache.org/guides/mini/guide-http-settings.html#Maven_3.0.4 https://maven.apache.org/guides/mini/guide-http-settings.html#Maven_3.0.4因此 - 我们的场景如下:

Project

-- 模块 1 - 下载一些 pom/jars - 保持连接活动

-- 模块 2 - 运行一些插件/测试 - 持续超过 5 分钟

-- 模块 3 - 尝试下载一些 pom/jar

Azure - NAT 配置:https://github.com/wbuchwalter/azure-content/blob/master/includes/guidance-tcp-session-timeout-include.md https://github.com/wbuchwalter/azure-content/blob/master/includes/guidance-tcp-session-timeout-include.md4 分钟后终止所有空闲连接。

因此,在模块 2 执行期间,模块 1 最初打开和使用的所有连接都被关闭,而模块 3 并不知道这一点。

我们的解决方案 - 鉴于无法配置 NAT 4 分钟超时 - 是使用 tcp keep-alive 或强制 Maven 使用不同的连接池实现或使用驱逐管理器在 NAT 之前“很好地”关闭这些空闲连接“强行”关闭它们。


None

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

在 Azure 上的 Docker 容器内运行时,Maven 构建下载工件连接缓慢/重置 的相关文章

随机推荐