У нас есть образ докера, который запускает команду git clone для определенного репозитория, а затем запускает сборку maven.Когда этот образ запускается локально, он работает нормально.При запуске этого образа на виртуальной машине AWS он работает нормально.
Проблема, с которой мы сталкиваемся, заключается в том, что при запуске этого образа внутри ACI (экземпляры контейнера Azure) или на виртуальной машине Azure - этап загрузки артефактов внутри maven.У сборки есть некоторые проблемы с подключением - загрузка JAR очень сильно (иногда) замедляется - и даже тайм-аут (иногда).
Мы настраиваем хранилище, созданное с этим образом - и проблема тайм-аута возникает только нанесколько проектов.Насколько мы можем судить, эти проекты не имеют ничего особенного.
Для конкретной конфигурации команд vm и mvn, которые мы фактически выполняем - проблема с подключением возникает при одном и том же наборе артефактов.
Если мы изменим команды mvn - место возникновения проблемы с подключением изменится.
Изначально у нас была одна команда mvn clean package
, выполненная после клона git, - которая вызвала проблемуна конкретном наборе банок.Затем мы добавили mvn dependency:resolve-plugins
, mvn compile dependency:resolve
и, наконец, mvn clean package
.Мы сделали это, потому что думали, что некоторые тесты, которые выполнялись изначально, могли вызвать проблемы с подключением - и поэтому мы сначала перенесли шаг загрузки артефакта.Это не решило проблему - просто изменили место, где зависают загрузки jar.
Изменена конфигурация подсчета потоков mvn, а также размер ядра и памяти виртуальной машины - но это не помогло.
Мы установили флажок TCP Keepalive на ВМ - чтобы избежать возможного тайм-аута Azure NAT / Load Balancer, который убивал наши соединения.Это решение было предложено службой поддержки Azure, и мы также нашли его здесь: Сборка Maven получает сброс соединения при загрузке артефактов Мы настроили его на основе руководства по Azure: 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)
Обратите внимание на подозрительные: (151 кБ при 159 б / с), (80 кБ при 84 б / с), (744 кБ при 788B / s)
У нас есть примеры выполнений, которые выполняются очень хорошо - и примеры выполнения с тайм-аутом (1 час) - и примеры выполнения, которые занимают около 1 часа.
Решения:
У нас есть опции для предварительного кэширования некоторых jar-файлов в исходном образе докера - и, следовательно, не требуется maven для их обработки.Но образ докера, который обрабатывает эту сборку, должен запускаться для любого git-репо (Java + Maven), и мы не можем знать, какие зависимости имеют эти проекты.
Как и в другом пункте, есть опции для создания внешнего тома, который используется совместно для работающих контейнеров, и для кэширования там jar-файлов.
У нас есть варианты перезапустить сборку maven после сбоя, потому что часть зависимостей уже была бы загружена, и она не застрянет в одном месте.
Мы обратились к Azureподдержку, и они рекомендовали конфигурацию TCP Keep-alive - но это не решило нашу проблему.
Мы хотим понять основную причину проблемы - это конфигурация докера?это ошибка мавена?это лазурный вопрос?Проблема с подключением возникает примерно в 9/10 случаях - у меня нет идеи, почему это работает, - и я не знаю, почему это не работает :) Решения, которые я упоминал ранее, - это просто обходные пути - они не исправляют это - просто игнорируют это.
Обнаружена проблема
Проблема заключается в том, что Maven повторно использует те же HTTP-соединения для загрузки файлов pom / jar.https://maven.apache.org/guides/mini/guide-http-settings.html#Maven_3.0.4 Таким образом - наш сценарий имеет следующие черты:
Проект
- модуль 1 - загрузить несколько pom / jar - сохранить соединение активным
-- модуль 2 - запускает некоторые плагины / тесты - длится более 5 минут
- модуль 3 - пытается загрузить некоторые pom / jars
Azure - конфигурация NAT: https://github.com/wbuchwalter/azure-content/blob/master/includes/guidance-tcp-session-timeout-include.md убивает любые простаивающие соединения через 4 минуты.
Таким образом, во время выполнения модуля 2 - все соединения, первоначально открытые и используемые модулем 1, закрываются - и модуль 3 не знает об этом.
Наше решение - учитывая, что тайм-аут NAT 4 минуты не может бытьсконфигурировано - это использовать tcp keep-alive или заставить Maven использовать другую реализацию пула соединений или использовать диспетчер удаления, чтобы «красиво» закрыть эти незанятые соединения, прежде чем NAT сможет их принудительно закрыть.