13 июля 2021

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Backend Java Developer
Domain Driven Design дает большие возможности по созданию крупных проектов, которые в будущем становятся надежными и легко масштабируемыми. Как пройти полный проектный цикл, от бизнес-модели до AWS?
3
☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)
В первой части цикла мы подготовили необходимый инструментарий: Git/GitHub, SSH, Spring Boot и Docker. Завершая настройку среды для реализации проекта, мы продолжим разбираться с Docker и Spring Boot, а также познакомимся с Docker Hub и WS ECS Fargate. В третьей части перейдем к архитектуре.
***

Устанавливаем Docker на локальную машину Ubuntu

В консоли набираем команды, обновляем систему:

        $ sudo apt update && sudo apt upgrade
    

Устанавливаем дополнительные пакеты ядра для Docker контейнеров:

        $ sudo apt install --reinstall linux-image-generic
    

Перезагружаем машину и вводим следующую команду:

        $ sudo apt install linux-modules-extra-$(uname -r) linux-image-extra-virtual
    

Также устанавливаем пакеты для работы по HTTPS:

        $ sudo apt install apt-transport-https ca-certificates curl software-properties-common
    

Добавляем ключ репозитория:

        $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    

Добавляем сам репозиторий Docker:

        $ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
    

Еще раз обновляемся:

        $ sudo apt update && apt-cache policy docker-ce
    

Устанавливаем Docker:

        $ sudo apt install -y docker-ce
    
☕ Подтянуть свои знания по Java вы можете на нашем телеграм-канале «Библиотека Java для собеса»

Добавляем локального пользователя в группу docker:

        $ sudo usermod -aG docker $(whoami)
    

Перезагружаем машину и проверяем состояние установленного Docker:

        $ sudo systemctl status docker
    
Состояние активности Docker
Состояние активности Docker

Далее устанавливаем Docker Compose:

        $ sudo curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
    

Даем права на исполнение файла:

        $ sudo chmod +x /usr/local/bin/docker-compose

    

Проверяем:

        $ docker-compose --version
    
Состояние активности Docker Compose
Состояние активности Docker Compose
🧩☕ Интересные задачи по Java для практики можно найти на нашем телеграм-канале «Библиотека задач по Java»

Пробуем создать и запустить контейнер

Наш проект Spring Boot из предыдущей статьи нужно упаковать в контейнер. В корневой папке проекта в терминале вводим следующую команду:

        $ ./mvnw package && java -jar target/emc-0.0.1-SNAPSHOT.jar
    

Создаем Dockerfile

В корневой папке проекта создаем Dockerfile со следующим кодом

        FROM adoptopenjdk/openjdk11:alpine-jre
ARG JAR_FILE=target/emc-0.0.1-SNAPSHOT.jar
WORKDIR /opr/app
COPY $(JAR_FILE) app.jar
ENTRYPOINT [“java”,”-jar”,“app.jar”]

    
В интегрированной среде STS 4, Dockerfile должен выглядеть так.
В интегрированной среде STS 4, Dockerfile должен выглядеть так.

Здесь:

  • FROM adoptopenjdk/openjdk11:alpine-jre – загружается образ Alpine Linux с версией openjdk 11.
  • ARG JAR_FILE=target/emc-0.0.1-SNAPSHOT.jar – инструкция ARG создает переменную JAR_FILE, указывающую на местоположение jar-файла.
  • WORKDIR /opt/app – назначаем рабочую директорию.
  • COPY ${JAR_FILE} app.jar – скомпилированный jar файл emc-0.0.1-SNAPSHOT.jar копируется в рабочую директорию с новым именем app.jar.
  • ENTRYPOINT ["java","-jar","app.jar"] – из заданной рабочей директории запускается приложение app.jar.

Создаем Docker образ

Далее в корневой папке проекта запускаем следующую команду:

        $ docker build -t emc:0.0.1 .
    
Примечание:
Обратите внимание, в конце команды стоит точка, это означает что, создаем образ в текущей папке, а именно в папке /opt/app.
<span>Результат выполнения команды <code class="inline-code">build</code>.</span>
Результат выполнения команды build.

Проверяем созданный образ:

        $ docker images
    

Видим присутствие образа emc:

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Запускаем контейнер Docker

В терминале, выполним команду run:

        $ docker run -d -p 8080:8080 -t emc:0.0.1
    
Результат команды <code class="inline-code">run</code> должен быть таким.
Результат команды run должен быть таким.

Здесь:

  • параметр -d означает запуск в фоновом режиме;
  • параметр -p 8080:8080 означает соответствие портов между локальной машиной (левый 8080) и контейнером (правый 8080);
  • параметр -t , задает имя образа (имя:версия).

Проверяем контейнер Docker

Запущенный контейнер можно проверить двумя способами:

1. через команду curl:.

        $ curl http://localhost:8080/hello
    
Результат должен быть таким.
Результат должен быть таким.

2. набрав в браузере адрес localhost:8080/hello.

Далее останавливаем запущенные контейнеры:

        $ docker stop $(docker ps -a -q)
    
Контейнеры остановлены, образы присутствуют.
Контейнеры остановлены, образы присутствуют.

Не забываем зафиксировать изменения и отправить на GitHub

На локальной машине

В корневой папке текущего проекта выполняем последовательность git-команд. Проверяем состояние файлов и папок в нашем проекте:

        $ git status
    
При изменениях в файлах или папках, появится следующее.
При изменениях в файлах или папках, появится следующее.

Здесь наш новый Dockerfile не отслеживается.

Индексируем изменения командой add:

        $ git add Dockerfile
    

Еще раз проверяем состояние:

        $ git status
    
Измененный <code class="inline-code">Dockerfile</code> добавился в<code class="inline-code"> commit</code>.
Измененный Dockerfile добавился в commit.

Выполним команду commit:

        $ git commit -m "Dockerfile added to project"
    

Вносим изменения в удаленный репозиторий командой push:

        $ git push origin master
    

Конечный результат должен быть таким:

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

В репозитории GitHub

Идем на GitHub и проверяем присутствие файла Dockerfile:

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

С Docker и GitHub мы разобрались.

Используем Docker Hub

Если обратить внимание на код в Dockerfile, первая строка начинается так:

        FROM adoptopenjdk/openjdk11:alpine-jre
    

Здесь говорится о том, что образ (заготовка) adoptopenjdk/openjdk11:alpine-jre загрузится “откуда то”.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Эти “заготовки” готовых образов располагаются в реестре Docker Hub – в дальнейшем нам придется воспользоваться этим реестром.

Регистрация в Docker Hub

Для начала регистрируемся в Docker Hub, запоминаем Docker ID и пароль. На странице приветствия выбираем Create a Repository.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

В окне создания нового репозитория вводим имя emc и видимость репозитория public.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

На локальной машине

Переименуем локальный образ следующей командой:

        $ docker tag old_image_name:tagname new_image_name:new_tag
    

Как пример. К имени образа emc:0.0.1 я добавил свой Docker ID через знак слеша, и у меня получилось так:

        $ docker tag emc:0.0.1 barust67/emc:0.0.1
    

Проверяем результат:

        $ docker images
    

На локальной машине логинимся в Docker Hub со своим Docker ID:

        $ docker login -u barust67
    
Результат должен быть таким.
Результат должен быть таким.

Забрасываем (push) локальный образ в Docker Hub в репозиторий emc:

        $ docker push image_name:tag
    

В моем случае команда выглядит следующим образом:

        $ docker push barust67/emc:0.0.1
    
Результат должен быть таким.
Результат должен быть таким.

Идем в Docker Hub и убеждаемся в результате:

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)
☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

С Docker Hub тоже разобрались. Этот образ нам понадобится, когда будем настраивать AWS.

Переходим к последнему этапу подготовительной части: нам нужно будет запустить проект в Amazon Web Services.

AWS

Мы будем использовать AWS ECS Fargate. С регистрацией в AWS проблем не должно возникнуть: чтобы использовать Free версию, достаточно представить Visa карту с $1 на счету. В процессе работы с AWS вы можете использовать AWS CLI на локальной машине или AWS Management Console непосредственно на сайте AWS. Для большей наглядности начнем с AWS Management Console.

Работаем с AWS Management Console и настраиваем кластер под Fargate

В AWS Management Console, выберите Elastic Container Service (ECS):

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Выберите опцию Clusters:

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)
Если вы еще не создавали кластеры, окно должно выглядеть так.
Если вы еще не создавали кластеры, окно должно выглядеть так.

Выберите Create Cluster, опцию Networking only и нажмите кнопку Next step.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Задайте имя кластера (я назвал свой AWS-Fargate-Claster) и отметьте опцию CloudWatch Container Insights. Нажмите на кнопку Create.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)
Кластер должен выглядеть так.
Кластер должен выглядеть так.
☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Создаем Task Definitions

В окне Task Definitions выберите Create new Task Definition:

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

На первом шаге выберите тип запуска Fargate и нажмите на кнопку Next step:

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Далее задайте имя задачи (в нашем случае – emc), выберите task role (ecsTaskExecutionRole), в Task memory выберите 0,5GB, а в опции Task CPU (vCPU) – 0,25 vCPU, затем нажмите на кнопку Add container:

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Окно Add container состоит из двух разделов: Standard и Advanced container configuration.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Заносим данные в разделе Standard. В Container name я задал имя emc, в поле Imagebarust67/emc:0.0.1, в поле Port mappings8080. В конце нужно нажать на кнопку Add.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)
Мы добавили контейнер.
Мы добавили контейнер.

Для завершения в самом низу окна второго шага нажмите кнопку Create. В результате должно появиться такое окно:

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)
Задачу мы определили и окно <b>Task Definitions</b> должно выглядеть так.
Задачу мы определили и окно Task Definitions должно выглядеть так.

Возвращаемся в раздел Clusters и заходим в наш кластер AWS-Fargate-Cluster.

Создаем сервис для кластера AWS-Fargate-Cluster

Создаем новый сервис для нашего кластера, нажав на кнопку Create:

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Создание сервиса состоит из четырех шагов. На первом выбираем Launch type – Fargate, Task Definition определяем как – emc, в Service name задаем имя – emc-service, Number of tasks определяем как – 1.

Нажимаем кнопку Next step.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Выберите Cluster VPS – здесь по умолчанию, выберите Subnets (любой) и далее в опции Security groups нажмите на кнопку Edit

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Так как в проекте мы определили порт TCP 8080, необходимо открыть в нашем сервисе этот порт. В окне Configure security groups нажмите на кнопку Add rule, в добавленной строке поменяйте тип на Custom TCP, пропишите порт 8080 и нажмите на кнопку Save

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Оставляя другие опции по умолчанию, нажимаем на кнопку Next step и переходим к третьему шагу. Здесь оставляем все как есть, нажимаем на кнопку Next step и переходим к четвертому шагу.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Нажмите на кнопку Create service и завершите создание сервиса. Если немного подождать, в появившемся окне данные должны быть примерно такими:

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Далее нажимаем на кнопку View service и просматриваем наш сервис. В категории Tasks выбираем нашу задачу

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

В окне задачи убеждаемся, что это наша задача и запоминаем Public IP. В вашем случае, IP будет другим

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

В адресной строке браузера вводим http://3.21.190.246:8080/hello , где вместо localhost мы прописали IP задачи на AWS.

☕ Пример проекта Java Backend: DDD, микросервисы, Spring Cloud и AWS (Часть 2)

Наше приложение запущено в облаке AWS. Можно налить чашку кофе и наслаждаться работой своего «Hello World!» в облаке Amazon.

Примечание
Все команды и картинки были проверены выполнены в реальном режиме. Ошибок у вас не должно быть.

Резюме

Мы завершили рассмотрение Docker, настроили Docker Hub для проекта и смогли развернуть его на AWS ECS Fargate.

***

В следующей статье мы перейдем ко второму этапу цикла по DDD, Microservices, Spring Cloud и AWS: подробнее рассмотрим подход DDD (Domain Driven Design) и сделаем наброски будущей модели проекта.

МЕРОПРИЯТИЯ

Комментарии

 
 
24 июля 2021

Спасибо за труд, ждем продолжения

15 июля 2021

Очень круто, спасибо. Жду следующих статей.

15 июля 2021

Спасибо, третья статья уже на подходе

ВАКАНСИИ

Добавить вакансию
Go-разработчик
по итогам собеседования
Middle/Senior C++ HFT разработчик
Москва, по итогам собеседования
Ведущий SRE инженер
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ

LIVE >

Подпишись

на push-уведомления