Как я могу оптимизировать сборки Docker для нескольких связанных Java-проектов Maven?(Кэширование) - PullRequest
0 голосов
/ 14 октября 2018

Я управляю большой собственной системой, которая скомпрометирована с дюжиной сервисов в Java.У нас есть базовый набор java-библиотек, которые все они совместно используют), и все компоненты / приложения создаются с использованием maven.За пределами ядра SDK jar, хотя у каждого приложения есть свой уникальный набор зависимостей.Я не могу понять, каков наилучший подход к созданию и развертыванию в докере.В идеале мне нужен весь жизненный цикл в докере с использованием многоэтапного подхода к сборке.Но я не вижу, как оптимизировать это с огромным количеством зависимостей.

Похоже, я могу сделать 2 подхода.

  1. Сборка, как мы делали раньшеиспользование maven и общего кэша на сервере CI (jenkins), чтобы зависимости выбирались один раз, кэшировались и были доступны для всех приложений.Затем создайте файл Docker для каждого приложения, которое просто копирует jar продукта и его зависимости (или толстый jar) в контейнер, и настройте его на выполнение.Недостатком этого подхода является то, что сама сборка может отличаться между разработчиками и CI-сервером.Потенциально использовать локальный кеш maven, например, nexus, только чтобы каждый раз не извлекать deps из интернета?Но это по-прежнему не решает проблему, заключающуюся в том, что сборка dev не обязательно будет соответствовать среде сборки CI.

  2. Использовать многоступенчатый файл dockerfile для каждого проекта.Я попробовал это, и это работает, и мне удалось поместить слой зависимостей maven в кеш, чтобы он не загружался слишком часто.К сожалению, этот промежуточный уровень сборки составлял 1-2 ГБ на приложение, и я не могу удалить «висячие» промежуточные звенья из демона, или все кеширование улетучивается.Это также означает, что в банках есть огромное количество дубликатов, которые нужно загружать для каждого приложения, если что-то меняется в poms.(то есть все они используют junit и log4j и многие другие сходства)

Есть ли способ решить эту проблему оптимально, чего я не вижу?Все блоги, которые я нашел, в основном сосредоточены на двух подходах, описанных выше (некоторые из них посвящены запуску самого maven в контейнере, что для меня ничего не решает).Возможно, мне придется в конечном итоге перейти к варианту 1, если других хороших решений не будет.

Я проверил стек-потоки и блоги, и все, что я могу найти, похоже, предполагает, что вына самом деле это просто создание одного приложения, а не их набора, в котором важно не повторять загрузку зависимостей.

1 Ответ

0 голосов
/ 15 октября 2018

Я думаю, что можно использовать кеш файловой системы .m2 / repository, если вы установили опцию --update-snapshots в вашей сборке maven.Он лучше масштабируется, потому что вы кэшируете каждый файл .jar только один раз для каждой среды сборки, а не один раз для каждого приложения.Кроме того, изменение в одной зависимости не делает недействительным весь кеш, что может иметь место, если вы используете кеширование на уровне докера.

К сожалению, в настоящее время это не может хорошо сочетаться с многоэтапными сборками, ноВы не единственный, кто просит об этом. Эта проблема требует добавления опции --volume в команду сборки docker. В этом запрашивается разрешение таких инструкций в Dockerfile: RUN --mount=m2repo=/var/mvn/repo mvn install.

Обе функции позволят вам использовать локальный кеш файловой системы maven во время многоступенчатой ​​сборки.

На данный момент я бы посоветовал сохранить ваш вариант 1 в качестве решения, если только вы не сталкиваетесь со многими проблемами, связанными с различными средами сборки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...