Простое обновление зависимостей сборки во многих микросервисах - PullRequest
1 голос
/ 29 февраля 2020

Использование общих библиотек в микросервисах - плохая практика. Но каждый микросервис зависит от фреймворков и библиотек: Spring Boot, Kafka Java Client et c.

Если система состоит из 30 микросервисов на основе Spring Boot и использует Gradle или Maven в качестве сборки инструмент и распространяется в виде Docker изображений, есть ли простой способ обновить версию Spring Boot во всех микросервисах? Обновление всех микросервисов по одному занимает много усилий. И чем больше микросервисов в системе, тем больше усилий требуется.

И причиной обновления может быть уязвимость безопасности в некоторых зависимостях. Например, Spring Boot 2.2.0.RELEASE зависит от Tomcat 9.0.27, который имеет уязвимость CVE-2020-1938 (просто в качестве примера). Уязвимость была исправлена ​​в Tomcat 9.0.31, поэтому обновление до Spring Boot 2.2.4.RELEASE решит проблему.

Обходной путь - объявить версию Spring Boot в build.gradle как 2.2.+. Но кто-то все еще должен перестроить все микросервисы (например, на Jenkins).

Кроме того, при таком подходе вы теряете контроль над управлением версиями и делегируете его Gradle (всегда используйте последнюю возможную версию). Чтобы все еще иметь контроль над зависимостями, версии могут быть объявлены в gradle.properties и каким-то образом смонтированы Дженкинсом в рабочую область:

spring.version=2.2.4.RELEASE

Если уязвимость является критической, нет времени ждать новой версии Spring Boot с исправлением и Tomcat должен быть явно обновлен в build.gradle. Или даже заменить на Undertow, что также требует изменений в build.gradle.

Использование автономного Tomcat вместо встроенного также не очень помогает, поскольку микросервисы распространяются как образы Docker, а не как файлы WAR, развернутые в контейнер сервлетов.

В Java Обновления безопасности EE в теории было супер просто. Вы обновляете сервер приложений (например, WildFly) или устанавливаете исправление безопасности, и если приложение использует только Java EE API, никаких дальнейших действий не требуется. Существует ли аналогичная концепция простых обновлений зависимостей для микросервисов (по крайней мере, в теории)?

Ответы [ 2 ]

1 голос
/ 01 марта 2020

В качестве дополнительного примечания, микросервисы приносят пользу, делая компоненты более автономными и обслуживаемыми, но это также имеет свои издержки: их интеграция и обслуживание не дешевы. Таким образом, гранулярность микросервисов также должна рассматриваться в этом аспекте.

Если система состоит из 30 микросервисов, основанных на Spring Boot и использующих Gradle или Maven в качестве средства сборки и распространяемых в виде Docker образов, существует ли простой способ обновить версию Spring Boot на всех микросервисах ? Обновление всех микросервисов по одному занимает много усилий. И чем больше микросервисов в системе, тем больше усилий требуется.

С помощью инструментов CI, как цитирует Jenkins, соответствующие автоматические тесты в каждом приложении микросервиса, что не так сложно обновить весеннюю версию их файл pom / gradle и даже для их развертывания в среде интеграции с инструментами ИТ-инфраструктуры автоматизации, например Ansible.
. В общем случае обновление версии зависимостей всех проектов можно выполнить с помощью плагина maven / gradle, если проекты принадлежат к многомодульному проекту (плагин Maven версии и плагин Gradle версии делают это).
Если проекты не относятся к многомодульному проекту, есть и альтернатива, но вы должны добавить шаг поиска SCM вручную.
Весь задание может быть выполнено с помощью сценария оболочки или, что еще лучше, с заданием jenkins, принимающим в качестве пользовательского параметра задания используемую версию весенней загрузки, которую можно выполнять по требованию. С Jenkins это по-прежнему приятнее, потому что вы можете написать конвейерное задание, которое интегрирует как извлечение SCM, docker агент, выполнение сборки, так и выполнение оболочки при необходимости. И в целом вы сохраняете все детали выполненных шагов (успех как неудача) в инструменте, который использует ваша команда.

В Java Обновления безопасности EE в теории были очень просты. Вы обновляете сервер приложений (например, WildFly) или устанавливаете исправление безопасности, и если приложение использует только Java EE API, никаких дальнейших действий не требуется

По моим недавним воспоминаниям, обновление Java EE Серверы во всех средах никогда не были легкой задачей (не такой простой, как обновление версии в файле).
Официальные процедуры обновления Weblogi c и Websphere очень требовательны, обновления также занимают много времени, потому что эти серверы как бы сказать ... раздувать, и откат к предыдущей версии тоже не всегда прост.

0 голосов
/ 29 марта 2020

Благодаря davidxxx answer Я нашел решение, которое считаю чистым и легким.

Общая идея состоит в том, чтобы просто автоматизировать процесс ручного управления обновление версий библиотек вместо использования обходного пути (например, Dynami c версии 1.+ создание сборок недетерминированных c, монтирование с централизованным управлением gradle.properties в Jenkins et c.).

  1. Используйте спецификацию (спецификацию), которая представляет собой особый вид POM, который объединяет несколько зависимостей и предоставляет их версии.

    dependencies {
        implementation platform("org.springframework.boot:spring-boot-dependencies:${springBootVersion}")
        implementation platform("org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}")
    
        implementation 'org.springframework.boot:spring-boot-starter-web' //version is taken from BOM
        implementation 'org.springframework.cloud:spring-cloud-context' //version is taken from BOM
        //...
    }
    
  2. Создайте пользовательскую спецификацию с указанными вами c зависимостей, как описано в ответе

    dependencies {
        //...
        implementation platform("com.example:my-dependencies:${myBomVersion}")
        //...
    }
    
  3. Таким образом, в build.gradle только спецификациях будут объявлены версии. Все остальные зависимости будут использовать версии, предоставленные спецификациями. Объявите версии спецификации в gradle.properties

    springBootVersion=2.2.4.RELEASE
    springCloudVersion=Hoxton.SR1
    myBomVersion=1.0.0
    
  4. Чтобы обновить зависимости, вам нужно только обновить версию спецификации в gradle.properties. Эта задача может быть автоматизирована с помощью sed

    sed -i'.original' -E 's|(springBootVersion)=(.+)|\1=2.2.6.RELEASE|g' gradle.properties
    
  5. Сценарий Bash для обновления версий может быть создан, например, ./update-version.sh springBootVersion 2.2.6.RELEASE и вызван в параметризованном задании Jenkins. Репозиторий, имя переменной версии и значение новой версии могут быть предоставлены в качестве параметров.

Описанный подход немного упрощает процесс обновления библиотек при наличии детерминированных c сборок (вы всегда знаете, какие версии библиотеки используются).

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