Вы находитесь на странице: 1из 31

ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ АВТОНОМНОЕ ОБРАЗОВАТЕЛЬНОЕ

УЧРЕЖДЕНИЕ ВЫСШЕГО ОБРАЗОВАНИЯ


«САНКТ-ПЕТЕРБУРГСКИЙ ПОЛИТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ
ПЕТРА ВЕЛИКОГО»
Институт компьютерных наук и технологий

Отчет о прохождении учебной производственной (технологической


(проектно-технологической)) практики

Епимахова Дарья Сергеевна

3 курс, 3530203/00102

02.03.03 Математическое обеспечение и администрирование информационных


систем

Место прохождения практики: Публичное акционерное общество "Сбербанк


Россия" , г. Санкт-Петербург, Старо-Петергофский просп., д. 30 к.1
Сроки практики: с 10.06.2023 по 8.07.2023
Руководитель практической подготовки от ФГАОУ ВО «СПбПУ»: Пак Вадим
Геннадьевич, к.ф.-м.н., доцент ВШИИ
Консультант практической подготовки от ФГАОУ ВО «СПбПУ»: нет
Руководитель практической подготовки от профильной организации: Зенин
Александр Юрьевич, руководитель направления, Управление развития технологий
дивизиона «Корпоративные клиенты 360»
Оценка: отлично

Руководитель практической подготовки


от ФГАОУ ВО «СПбПУ»: /В.Г. Пак/

Руководитель практической подготовки


от профильной организации: /А.Ю. Зенин/

Обучающийся: /Д.С. Епимахова/

Дата: 07.07.2023
2

СОДЕРЖАНИЕ

Введение ........................................................................................................ 3
Глава 1. Теоретическая часть......................................................................... 4
1.1. Микросервисная архитектура ................................................................ 4
1.2. REST API ................................................................................................ 6
1.3. Spring Boot .............................................................................................. 7
1.4. Spring Scheduler ...................................................................................... 9
1.5. Feign Client.............................................................................................. 10
1.6. Apache Kafka ........................................................................................... 11
1.7. Docker...................................................................................................... 13
Глава 2. Практическая часть ......................................................................... 18
2.1. Технологии .............................................................................................. 18
2.2. Контейнеризация Postgres и PgAdmin, создание базы данных .............. 18
2.3. Настройке Apache Kafka с помощью Docker.......................................... 20
2.4. Создание микросервисов........................................................................ 22
2.4.1. Alpha..................................................................................................... 23
2.4.2. Beta ....................................................................................................... 24
2.4.3. Gamma.................................................................................................. 25
2.5. Взаимодействие микросервисов ............................................................. 27
Заключение .................................................................................................... 28
Список использованных источников............................................................. 29
Приложение 1. Код контроллера Alpha......................................................... 30
3

ВВЕДЕНИЕ

Цель данной практики заключается в ознакомлении с понятием микро­


сервисной архитектуры, изучении возможностей и методов взаимосвязи между
сервисами в рамках микросервисной системы, а также в создании демонстра­
ционной микросервисной системы с использованием изученных программных
продуктов.
Для достижения цели были поставлены задачи:
1. Изучить необходимый теоретический материал для работы с указанными
ниже программными продуктами.
2. Реализовать демонстрационное приложение.
3. Продемонстрировать работу приложения.
Предлагается разработать демонстрационную систему, предназначенную
для сбора и обработки данных, полученных от погодных датчиков. Данная система
состоит из трех взаимосвязанных приложений: alpha, beta и gamma. Alpha отвечает
за сбор данных и передачу их второму приложению, beta записывает полученные
данные в базу данных и передает их на обработку третьему приложению, а gamma
выполняет обработку поступивших данных и сохраняет их в базе данных.
Архитектура системы базируется на принципах REST и использует фрейм­
ворк Spring Boot. Приложения beta и gamma взаимодействуют с базой данных
PostgreSQL. Взаимосвязь между приложениями alpha и beta осуществляется с
использованием Apache Kafka, а между приложениями beta и gamma - с помощью
Feign Client. Для тестирования функциональности приложений используются
инструменты Postman и Offset Explorer.
Язык программирования для реализации системы - Java 17.
4

ГЛАВА 1. ТЕОРЕТИЧЕСКАЯ ЧАСТЬ

1.1. Микросервисная архитектура

Микросервисная архитектура – это подход к разработке программного обес­


печения, в котором приложение строится из набора маленьких, независимых и
взаимодействующих между собой сервисов (рис. 1.1). Каждый сервис работает
автономно, выполняя определенную функцию, имеет свою базу данных и/или внут­
реннее хранилище и может быть развернут, масштабирован и обновлен независимо
от других сервисов в системе.

Рис.1.1. Пример архитектуры микросервисной системы

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


протоколы связи, например, HTTP, и может включать передачу данных, вызов
удаленных процедур или событий. Обычно Микросервисы ориентированы на
предоставление API (Application Programming Interface), чтобы другие сервисы
или клиенты могли использовать их функциональность.
Микросервисная архитектура обеспечивает ряд преимуществ:
– Гибкость и масштабируемость: Микросервисы могут быть разработаны,
развернуты и масштабированы независимо друг от друга, что позволяет
5

гибко настраивать систему под изменяющиеся требования и обрабатывать


высокую нагрузку путем добавления новых экземпляров сервисов.
– Независимость разработки и развертывания: Каждый микросервис может
быть разработан и развернут независимо, что упрощает сопровождение и
обновление системы, а также позволяет сократить время внедрения новых
функций и исправлений ошибок.
– Распределение обязанностей: Каждый микросервис выполняет определен­
ную функцию или область ответственности, что способствует улучшению
отдельности обязанностей и упрощению понимания кода. Это также поз­
воляет использовать разные технологии и языки программирования в
разных сервисах.
– Повышенная устойчивость: Если один сервис выходит из строя, остальные
сервисы продолжают работу, что увеличивает устойчивость системы в
целом.
Однако такой подход также вносит дополнительные сложности:
– Сложность управления: Распределенные системы на основе микросервисов
требуют управления связностью, согласованностью данных и управле­
ния распределенными транзакциями. Это может быть сложной задачей,
особенно при масштабировании системы.
– Увеличенная сложность тестирования: Интеграционное тестирование и
отладка распределенных микросервисов могут быть сложными, поскольку
требуется проверка взаимодействия между разными сервисами.
– Затраты на коммуникацию: Взаимодействие между микросервисами осу­
ществляется через сеть, что может привести к дополнительным накладным
расходам на коммуникацию и протоколы.
– Сложность развертывания и управления инфраструктурой: Микросервисы
требуют хорошо организованной и масштабируемой инфраструктуры, что
может потребовать дополнительных усилий и ресурсов.
В целом, микросервисная архитектура представляет собой мощный подход к
разработке распределенных систем, позволяющий создавать гибкие, масштабируе­
мые и легко сопровождаемые приложения. Однако для того, чтобы воспользоваться
преимуществами этого подхода необходимы тщательный анализ и планирование
бизнес логики и связей между сервисами [5].
6

1.2. REST API

REST API — это прикладной программный интерфейс, который исполь­


зует HTTP-запросы для получения, извлечения, размещения и удаления данных.
Аббревиатура REST в контексте API расшифровывается как «передача состо­
яния представления» (Representational State Transfer). API REST (или RESTful)
основан на передаче состояния представлений, архитектурном стиле и подходе к
коммуникациям, часто используемым при разработке веб-служб.
Принципы REST API определены в диссертации его создателя Роя Филдинга.
Основные из них:
– единый интерфейс;
– разграничение клиента и сервера;
– нет сохранения состояния;
– кэширование всегда разрешено;
– многоуровневая система;
– код предоставляется по запросу.
По сути REST API функционирует как шлюз между клиентами и ресурсами
в Интернете.
Клиенты — это пользователи, которые хотят получить доступ к информации
в Интернете.
Ресурсы — это информация, которую различные приложения предоставляют
своим клиентам.
Базовый принцип работы RESTful API совпадает с принципом работы в
Интернете. Клиент связывается с сервером с помощью API, когда ему требуется
какой-либо ресурс. Разработчики описывают принцип использования REST API
клиентом в документации на API серверного приложения.
RESTful API требует, чтобы запросы содержали:
– Уникальный идентификатор ресурса;
– Один из методов:
• GET — метод чтения информации;
• POST — создание новых записей;
• PUT — редактирование записей;
• GET — метод чтения информации;
– Заголовки HTTP (метаданные).
А ответы содержали:
7

– Код состояния (Например: 200 – общий ответ об успешном исполнении


метода; 500 – любая внутренняя ошибка сервера, которая не входит в
рамки остальных ошибок класса);
– Текст сообщения (Например, в формате JSON);
– Метаданные об ответе (название сервера, кодировка, дата и тип данных).
Архитектура REST API — самое популярное решение для организации
взаимодействия между различными программами, поскольку HTTP-протокол
реализован во всех языках программирования и всех операционных системах [6].

1.3. Spring Boot

В качестве программной платформы приложений выступает фреймворк


Spring Boot.
Spring — это проект с открытым кодом, предлагающий простой модульный
подход к созданию приложений в Java, нацелены на упрощение написания при­
ложений. Само по себе название Spring обычно относится к исполняющей среде
или группе проектов целиком, также называемых модулями. Spring Boot — это
отдельный модуль, созданный как расширение платформы Spring.
Некоторые основные возможности Spring Boot:
– Автономные приложения — Spring Boot помогает создавать приложения,
не привязанные к определенной платформе и способные работать локально
на устройстве без подключения к Интернету или установки других служб.
– Встроенные серверы — Spring Boot позволяет напрямую внедрять серверы,
такие как Tomcat, Jetty и Undertow.
– Подход на основе рекомендаций — Spring Boot упрощает конфигурации
сборок, предоставляя рекомендации о начальных зависимостях.
– Автоматическая настройка — Spring Boot автоматически настраивает
Spring и другие сторонние библиотеки, если это возможно.
– Готовые функции — Spring Boot предоставляет готовые к работе ком­
поненты, такие как метрики, проверки работоспособности и внешнюю
конфигурацию.
Преимущества Spring Boot:
– Сокращает время разработки и повышает производительность — Spring
Boot упрощает разработку приложений на основе Spring с помощью Java.
Подход к платформе Spring на основе рекомендаций сокращает время,
8

затраченное на принятие решений и повторяющиеся задачи, и позволяет


сосредоточиться на создании и тестировании приложений.
– Снижает необходимость написания шаблонного кода, заметок и конфи­
гурацииm XML — разработчикам не придется писать код, настраивать
XML или изучать платформу Spring, если они этого не хотят.
– Интегрирует приложения в семейство проектов Spring — приложения
Spring Boot легко интегрируются с другими проектами в экосистеме
платформы Spring, включая Spring Data, Spring Cloud, Spring Security, а
также другие доверенные облачные службы, такие как Microsoft Azure
Spring Cloud.
– Предоставляет инструменты для разработки и тестирования — с по­
мощью инструмента интерфейса командной строки (CLI) и внедренных
HTTP-серверов Spring Boot создание сред для разработки и тестирования
приложений на основе Spring становится проще.
– Предлагает подключаемые модули и инструменты для упрощения раз­
работки — Spring Boot предлагает подключаемые модули для работы
с базами данных в памяти, а также другие популярные инструменты
автоматизации сборки, такие как Apache Maven.
Архитектура Spring Boot многоуровневая, каждый уровень взаимодействует
со слоем непосредственно ниже или выше него (иерархическая структура). В
Spring Boot выделяют четыре уровня, представленных на рис. 1.2 [8].

Рис.1.2. Архитектура Spring Boot


9

– Уровень представления обрабатывает HTTP-запросы, преобразует пара­


метр JSON в объект, аутентифицирует запрос и передает его на бизнес–
уровень. Проще говоря, он состоит из представлений, т.е. фронтенд-части.
– Бизнес-уровень обрабатывает всю бизнес-логику. Он состоит из классов
обслуживания и использует службы, предоставляемые уровнями доступа
к данным. Он также выполняет авторизацию и проверку.
– Уровень сохраняемости содержит всю логику хранения и транслирует
бизнес-объекты из строк базы данных и обратно.
– Уровень базы данных, на котором выполняются операции CRUD (создание,
извлечение, обновление, удаление).

1.4. Spring Scheduler

Spring Scheduler – это планировщик задач в приложении на основе фрейм­


ворка Spring. Он предоставляет возможность определения и выполнения задач в
определенное время или с определенной периодичностью.
Для определения точного расписания выполнения задач используется ан­
нотация @Scheduled с выражением cron. Аннотация @Scheduled может быть
применена к методу в классе компонента, который будет выполнять задачу по
расписанию.
Выражение cron состоит из пяти или шести полей, разделенных пробелами.
Каждое поле представляет отдельную единицу времени и определяет частоту
выполнения задачи [7]. Пример выражения cron и их значения представлены на
рис. 1.3.

Рис.1.3. Структура выражения cron


10

1.5. Feign Client

Feign Client – это инструмент, который предоставляет простой и декларатив­


ный способ создания клиентов для взаимодействия с удаленными HTTP-сервисами
в микросервисной архитектуре. Он является частью библиотеки OpenFeign, разра­
ботанной для облегчения работы с HTTP-клиентами в распределенных системах.
Feign Client значительно упрощает взаимодействе между сервисами в мик­
росервисной архитектуре, так как он позволяет избежать необходимости вручную
создавать HTTP-клиенты и писать большой объем кода для взаимодействия с
удаленными сервисами. Вместо этого, разработчикам достаточно определить
интерфейс и аннотации, что делает код более компактным и читабельным [9].
Основные этапы организации общения сервисов через Feign Client:
– Определение интерфейса: Разработчик определяет интерфейс, который
описывает контракт взаимодействия с удаленным сервисом. В этом ин­
терфейсе указываются методы, которые будут вызываться для отправки
запросов к удаленному сервису.
– Конфигурация Feign Client: В конфигурации приложения или классе
конфигурации разработчик настраивает Feign Client, указывая URL уда­
ленного сервиса и другие параметры, такие как таймауты, заголовки и
формат данных.
– Вызов методов удаленного сервиса: В клиентском коде разработчик со­
здает экземпляр интерфейса, описывающего удаленный сервис, используя
механизм внедрения зависимостей или создавая его экземпляр вручную.
Затем вызываются методы этого интерфейса для отправки запросов к
удаленному сервису.
– Автоматическая сериализация и десериализация данных: При вызове
методов интерфейса Feign Client автоматически выполняет сериализацию
(преобразование) объектов данных в формат, указанный в аннотациях или
конфигурации Feign Client. Затем Feign Client отправляет HTTP-запрос на
указанный URL удаленного сервиса с данными запроса.
– Обработка ответов: После отправки запроса удаленный сервис обрабаты­
вает его и отправляет ответ обратно. Feign Client автоматически выполняет
десериализацию (преобразование) ответа из формата HTTP-ответа в объ­
ект данных, указанный в аннотациях или конфигурации Feign Client. Затем
ответ возвращается клиенту.
11

Важно отметить, что Feign Client облегчает отправку HTTP-запросов и


обработку ответов, скрывая детали протокола HTTP от разработчика. Он также
интегрируется с другими инструментами, такими как Ribbon, для балансировки
нагрузки между экземплярами удаленного сервиса.

1.6. Apache Kafka

Apache Kafka – это распределенная платформа с открытым исходным кодом,


предназначенная для обработки и передачи больших объемов потоковых данных в
реальном времени с высокой пропускной способностью и низкой задержкой. Струк­
турно Kafka состоит из трех основных элементов – производителей (producers),
потребителей (consumers) и Kafka кластера, обеспечивающего их связь (рис. 1.4)

Рис.1.4. Связь сервисов с помощью Apache Kafka

Основными компонентами кластера Kafka являются:


– Брокеры (Kafka Brokers): Брокеры представляют собой физические или
виртуальные серверы, на которых запущен Kafka. Они обрабатывают сооб­
щения, хранят и индексируют данные и обеспечивают передачу сообщений
между продюсерами и консьюмерами.
– Топики (Topics): Топики в Kafka представляют собой категории или темы
данных, в которых хранятся и организованы сообщения. Каждый топик
может быть разбит на несколько разделов (partitions) для обеспечения
параллельной обработки данных.
12

– Контроллер (Controller): Контроллер в кластере Kafka отвечает за управле­


ние и координацию работы брокеров. Он отслеживает состояние брокеров,
назначает лидеров для разделов топиков, решает конфликты и обеспечи­
вает согласованность
– ZooKeeper: ZooKeeper – это координационная служба, используемая Kafka
для управления состоянием и координации брокеров. Она хранит мета­
данные кластера и обеспечивает согласованность и надежность в работе
кластера.
Производитель – приложение или процесс, который генерирует сообщения –
отсылает сообщения в топик, а потребитель – приложение или процесс, который
получает сообщения – подписывается на соответствующий топик, считывает и
обрабатывает сообщения [1].
Apache Kafka обладает рядом преимуществ [2]:
– Высокая пропускная способность: Kafka способна обрабатывать и пе­
редавать потоки данных с очень высокой скоростью благодаря своей
архитектуре и оптимизациям. Она может справиться с миллионами сооб­
щений в секунду.
– Масштабируемость: Kafka разработана для горизонтального масштабиро­
вания, что позволяет добавлять новые брокеры в кластер для увеличения
пропускной способности и обработки больших объемов данных.
– Отказоустойчивость: Благодаря репликации данных и распределенной
архитектуре, Kafka обеспечивает высокую доступность и отказоустойчи­
вость. Даже при отказе одного или нескольких брокеров, данные остаются
доступными.
– Гарантированная доставка: Kafka обеспечивает гарантированную доставку
сообщений, что означает, что сообщения не будут потеряны и достигнут
конечного получателя.
– Гибкая хранение и сохранение сообщений: Kafka хранит сообщения в
длительное время, что позволяет задерживать обработку сообщений и
восстанавливаться после сбоев.
Однако, Apache Kafka не лишена и недостатков [2]:
– Сложность настройки и управления: Конфигурация и управление класте­
ром Kafka может быть сложным и требует некоторого опыта и экспертизы.
Необходимость правильно настроить параметры и мониторить состояние
кластера может быть вызовом для неподготовленных команд.
13

– использования ZooKeeper в качестве координирующей службы. Это до­


бавляет дополнительную точку отказа и увеличивает сложность конфигу­
рации.
– Ограниченная поддержка протоколов: Kafka специализируется на потоко­
вой обработке и не поддерживает полноценный запрос-ответ, что может
быть неподходящим для некоторых случаев использования.

1.7. Docker

Docker – это платформа с открытым исходным кодом, которая применяется


для разработки, тестирования, доставки и запуска веб-приложений в контейнери­
зированных средах. Он обеспечивает более эффективное использование ресурсов
системы, быстрое развертывание готовых программных продуктов, а также масшта­
бируемость и переносимость в другие окружения с гарантированной стабильностью
работы.
Основной принцип работы Docker заключается в контейнеризации приложе­
ний. Этот вид виртуализации позволяет упаковывать программное обеспечение в
изолированные среды - контейнеры. Каждый контейнер содержит все необходи­
мые компоненты для работы приложения. Это дает возможность одновременного
запуска большого количества контейнеров на одном хосте. Docker-контейнеры
могут работать на локальных серверах, облачные платформах, персональных
компьютерах и т.д.
Использование Docker имеет ряд преимуществ, таких как [3]:
– Минимальное потребление ресурсов: Контейнеры не виртуализируют всю
операционную систему, а используют ядро хоста и изолируют программу
на уровне процесса. Это приводит к снижению потребления ресурсов
локального компьютера по сравнению с виртуальными машинами.
– Скоростное развертывание: Docker-образы (шаблоны) позволяют исполь­
зовать уже готовые компоненты и не требуют установки и настройки
вспомогательных компонентов. Это сокращает время и усилия, необходи­
мые для развертывания приложений.
– Удобное скрытие процессов: Каждый контейнер может использовать раз­
ные методы обработки данных и скрывать фоновые процессы, что обеспе­
чивает удобство и гибкость в работе с приложениями.
14

– Работа с небезопасным кодом: Технология изоляции контейнеров позволя­


ет запускать любой код без вреда для операционной системы, обеспечивая
безопасность и изолированность приложений.
– Простое масштабирование: Docker позволяет легко масштабировать про­
екты, добавляя новые контейнеры и управляя нагрузкой. Это позволяет
эффективно управлять ростом и расширением приложений.
– Удобный запуск: Приложение, находящееся в контейнере, может быть
запущено на любом хосте, поддерживающем Docker, что облегчает пере­
носимость и развертывание приложений.
– Оптимизация файловой системы: Docker-образ состоит из слоев, что
позволяет эффективно использовать файловую систему и уменьшить
размер образа.
Docker состоит из нескольких связанных между собой компонетов (рис. 1.5)
[11]

Рис.1.5. Компоненты Docker

– Docker-демон (Docker daemon) - это сервер контейнеров, являющийся


частью программного обеспечения Docker. Демон управляет Docker-объ­
ектами, такими как сети, хранилища, образы и контейнеры. Он также
может взаимодействовать с другими демонами для управления сервисами
Docker.
15

– Docker-клиент (Docker client / CLI) - интерфейс взаимодействия поль­


зователя с Docker-демоном. Клиент Docker может взаимодействовать с
несколькими демонами, что обеспечивает гибкость и масштабируемость
при использовании Docker.
– Docker-образ (Docker image) - файл, который содержит зависимости,
данные и конфигурацию для дальнейшего развертывания и инициализации
контейнера. Образ является основой для создания и запуска контейнеров
Docker.
– Docker-файл (Dockerfile) - файл, содержащий набор инструкций для сборки
Docker-образа. В Docker-файле первая строка указывает базовый образ, а
последующие команды определяют, как скопировать файлы и установить
программы для создания определенной среды разработки.
– Docker-контейнер (Docker container) - легковесный, автономный пакет
программного обеспечения, который включает в себя все необходимое
для запуска приложения: код, среду выполнения, системные инструменты,
системные библиотеки и настройки. Контейнеры Docker изолированы друг
от друга и могут работать независимо друг от друга.
– Том (Volume) - это эмуляция файловой системы, используемая для чтения
и записи данных в контейнере. Том создается автоматически вместе с
контейнером и позволяет приложениям сохранять данные даже после
перезапуска контейнера.
– Реестр (Docker registry) - сервер, используемый для хранения Docker–
образов. Реестр Docker предоставляет место для размещения и обмена
образами Docker. Примеры реестров включают Docker Hub, который явля­
ется публичным реестром, а также приватные реестры, такие как Docker
Trusted Registry (DTR), используемые для хранения образов в локальной
сети компании.
– Docker-хост (Docker host) - это среда выполнения, в которой запускаются
контейнеры с программным обеспечением. Docker-хост может быть физи­
ческим или виртуальным сервером или даже персональным компьютером.
– Docker-сети (Docker networks) - это механизмы, используемые для ор­
ганизации сетевых интерфейсов между контейнерами и приложениями,
развернутыми в них. Docker-сети позволяют контейнерам общаться друг с
другом и с внешними ресурсами через определенные сетевые протоколы и
порты.
16

За связь между основными компонентами (реестром, образами и контейне­


рами) отвечает «Движок» Docker (Docker Engine) (рис. 1.6).

Рис.1.6. Структура Docker Engine

Движок в свою очередь состоит из сервера, REST API и клиента:


– Сервер выполняет инициализацию демона (фоновой программы), который
применяется для управления и модификации контейнеров, образов и
томов. API — механизм, отвечающий за организацию взаимодействия
Докер-клиента и Докер-демона.
– Клиент — позволяет пользователю взаимодействовать с сервером при
помощи команд, набираемых в интерфейсе (CLI).
Docker работает на основе клиент-серверной архитектуры, в основе которой
лежит взаимодействие между клиентом и веб-сервером (хостом). В этой модели
клиент отправляет запросы на получение данных, а сервер предоставляет эти
данные в ответ.
Docker-клиент предоставляет интерфейс, через который пользователь вза­
имодействует с Docker-демоном. Клиент может отправлять команды и запросы
Docker-демону для создания, запуска, остановки и управления контейнерами и
другими объектами Docker.
Docker-демон является сервером, который управляет Docker-объектами,
такими как контейнеры, образы, сети и тома. Он принимает команды от клиента,
обрабатывает их и выполняет соответствующие действия. Docker-демон также
может взаимодействовать с другими демонами для управления сервисами Docker
в распределенных средах.
17

Клиент и демон могут взаимодействовать между собой через различные


протоколы и интерфейсы, такие как командная строка (CLI), API или графиче­
ский интерфейс пользователя (GUI). Клиент отправляет запросы Docker-демону,
который обрабатывает их и возвращает результаты обратно клиенту.
Применение Docker не является универсальным и зависит от особенностей
проекта. В случае простых приложений, которые не требуют использования внеш­
них сервисов, Docker может быть достаточным для их развертывания. Однако,
при проектировании более сложных программных продуктов, которые включают
множество процессов и сервисов, рекомендуется использовать Docker Compose.
Docker Compose предоставляет средства для определения и управления
многоконтейнерными приложениями. Он позволяет определить конфигурацию
приложения в файле YAML, где можно указать сервисы, сети, объемы и дру­
гие параметры, необходимые для развертывания и взаимодействия компонентов
приложения.
Преимущества использования Docker Compose проявляются при проектиро­
вании сложных программных продуктов, таких как микросервисные архитектуры.
Он облегчает запуск и оркестрацию нескольких контейнеров, упрощает управление
зависимостями между сервисами и позволяет легко масштабировать и обновлять
приложения.
Однако, при разработке простых приложений, которые не требуют слож­
ной конфигурации или оркестрации множества сервисов, использование Docker
Compose может быть излишним и увеличить сложность развертывания. В таких
случаях, простое использование Docker для создания и запуска контейнеров может
быть более удобным и эффективным подходом.
Таким образом, Docker является важным инструментом для современных
разработчиков, предоставляя основу для виртуализации приложений на аппаратном
уровне. Эта технология обладает широким спектром функций и возможностей для
контроля процессов. Docker не только обеспечивает развертывание контейнеров,
но и позволяет оперативно масштабировать экземпляры контейнеров, работать с
многоконтейнерными приложениями, а также объединять несколько Docker-хостов
в единый кластер.
18

ГЛАВА 2. ПРАКТИЧЕСКАЯ ЧАСТЬ

2.1. Технологии

Перед началом работы были установлены следующие компоненты:


– Java Development Kit 17 (JDK) — бесплатно распространяемый компани­
ей Oracle Corporation (ранее Sun Microsystems) комплект разработчика
приложений на языке Java, включающий в себя компилятор Java (javac),
стандартные библиотеки классов Java, примеры, документацию, различные
утилиты и исполнительную систему Java (JRE).
– Apache Maven — фреймворк для автоматизации сборки проектов на основе
описания их структуры в файлах на языке POM (англ. Project Object Model)
– IntelliJ IDEA Ultimate — интегрированная среда разработки программного
обеспечения
– Lombok — это библиотека для сокращения кода в классах и расширения
функциональности языка Java.
– Kafkalityc — плагин IntelliJ IDEA позволяющий проверять и анализировать
работу Apache Kafka-кластера.
– Offset Explorer (ранее Kafka Tool) — это приложение с графическим
интерфейсом для управления и использования кластеров Apache Kafka
– Docker — программное обеспечение для автоматизации развёртывания
и управления приложениями в средах с поддержкой контейнеризации,
контейнеризатор приложений.
– Postman — это HTTP-клиент для тестирования API.
Операционная система локального хоста – Windows 11.

2.2. Контейнеризация Postgres и PgAdmin, создание базы данных

Для создания контейнеров использовались официальные образы postgres и


dpage/pgadmin4 опубликованные на Docker Hub. Запуск контейнеров происходит
командой run из консоли, при этом не обязательно перед этим клонировать образы
на хост, так как если при запуске контейнера используемый им образ не обнаружен,
он клонируется автоматически [3].
Параметры запуска контейнера для базы данных postgresql (рис. 2.1):
19

• -itd: Запуск контейнера в интерактивном режиме с возможностью подклю­


чения к его терминалу и демонизацией процесса (background mode).
• -e POSTGRES_USER=postgres: Определение переменной окружения
POSTGRES_USER со значением "postgres устанавливающей имя пользо­
вателя базы данных PostgreSQL.
• -e POSTGRES_PASSWORD=postgres: Определение переменной окружения
POSTGRES_PASSWORD со значением "postgres устанавливающей пароль
для пользователя базы данных PostgreSQL.
• -p 5432:5432: Проброс портов между хостом и контейнером. Порт 5432
внутри контейнера (стандартный порт PostgreSQL) привязывается к порту
5432 на хостовой машине, позволяя обращаться к базе данных через этот
порт на хосте.
• -v /data:/var/lib/postgresql/data: Примонтирование хостовой директории
/data внутри контейнера по пути /var/lib/postgresql/data. Это создает по­
стоянное хранилище для данных PostgreSQL, где /data на хосте будет
отображаться на /var/lib/postgresql/data в контейнере.
• –name postgresql: Задание имени контейнера как "postgresql".
• postgres: Имя используемого образа.

docker run - itd -e POSTGRES_USER = postgres -e


POSTGRES_PASSWORD = postgres -p 5432:5432 -v / data :/ var /
lib / postgresql / data -- name postgresql postgres

Рис.2.1. Консольная команда запуска контейнера для базы данных PostgreSQL

Параметры запуска контейнера для базы данных pgAdmin (рис. 2.2):


• –name pgadmin-postgres: Задание имени контейнера как "pgadmin-postgres".
• -p 5051:80: Проброс портов между хостом и контейнером. Порт 80 внутри
контейнера (стандартный порт для PgAdmin) привязывается к порту 5051
на хостовой машине, позволяя обращаться к PgAdmin через этот порт на
хосте.
• -e "PGADMIN_DEFAULT_EMAIL=user@postgres.com": Определение
переменной окружения PGADMIN_DEFAULT_EMAIL со значением
"user@postgres.com устанавливающей адрес электронной почты для
учетной записи администратора PgAdmin.
• -e "PGADMIN_DEFAULT_PASSWORD=postgres": Определение пере­
менной окружения PGADMIN_DEFAULT_PASSWORD со значением
20

"postgres устанавливающей пароль для учетной записи администратора


PgAdmin.
• -d: Запуск контейнера в фоновом режиме (detached mode).
• dpage/pgadmin4: Имя используемого образа, в данном случае, образ
PgAdmin 4.

docker run -- name pgadmin - postgres -p 5051:80 -e "


PGADMIN_DEFAULT_EMAIL = user@postgres . com " -e "
PGADMIN_DEFAULT_PASSWORD = postgres " -d dpage / pgadmin4

Рис.2.2. Консольная команда запуска контейнера для pgAdmin

Клонированные образы и запущенные контейнеры отобразились в Docker


Desktop (рис. 2.4, 2.3).

Рис.2.3. Образы PostgreSQL и pgAdmin

Рис.2.4. Контейнеры PostgreSQL и pgAdmin

PgAdmin доступен по адресу localhost:5051/login (рис. 2.5), где отобразилась


созданная база данных.

2.3. Настройке Apache Kafka с помощью Docker

Для настройки Apache Kafka в Docker использовался Docker Compose. Все


зависимости прописаны в файле docker-compose.yml, после чего кластер запущен
21

Рис.2.5. PgAdmin Web

через консоль командой docker-compose up (рис. 2.6) с параметрами –f c указанием


пути до конфигурационного файла и –d (detached mode) [4].

docker - compose -f docker - compose . yml up -d

Рис.2.6. Консольная команда запуска Apache Kafka в Docker

Созданный кластер отобразился в Docker Desktop (рис. 2.7) и к нему можно


подключиться с помощью Offset Explorer (рис. 2.8)

Рис.2.7. Кластер Kafka в Docker

Рис.2.8. Кластер Kafka в Offset Explorer


22

2.4. Создание микросервисов

Создание микросервисов начинается с разработки модели системы. Необ­


ходимо опередлить за какую задачу отвечает каждый сервис и каким образом он
связан с другими сервисами.
В данной демонстрационной микросервисной системе (рис. 2.9) представлен
процесс сбора и обработки данных о погодных условиях для вымышленного
объекта. Сервисы alpha и beta взаимодействуют друг с другом с помощью Apache
Kafka, где alpha выступает в роли производителя, а beta - потребителя. Это
позволяет эффективно передавать данные о погодных условиях от сервиса alpha
к сервису beta в реальном времени для дальнейшей обработки. Связь между
сервисами beta и gamma осуществляется с использованием Feign Client. Это
позволяет обеспечить удобный способ взаимодействия между сервисами и передачи
данных между ними. Сервисы beta и gamma также взаимодействуют с базой данных
PostgreSQL. Это позволяет сохранять и получать данные из базы данных для
обработки и хранения информации о погодных условиях.

Рис.2.9. Модель демонстрационной микросервисной системы

Для создания шаблонов приложений и добавления всх необходимых зависи­


мостей использовался Spring Initializr (рис. 2.10) [10].
Далее в созданных шаблонах реализовывался необходимый функционал.
Рассмотрим особенности каждого из приложений.
23

Рис.2.10. Создание шаблона для приложения gamma с помощью Spring Initializr

2.4.1. Alpha

Основной задачей приложения alpha является генерация сообщений, содер­


жащих показания датчиков, и их отправка в определенную тему Kafka. Время
отправки сообщений определяется планировщиком.
Для реализации данной функциональности необходимо настроить опреде­
ленные параметры в файле конфигурации application.properties. Эти параметры
включают в себя порт, на котором работает приложение alpha, адрес и порт сервера
Kafka, классы сериализаторов для ключей и значений, которые используются при
отправке сообщений в Kafka Topic, а также временной интервал cron (рис. 2.11).

server . port =8088

spring . kafka . producer . bootstrap - servers = localhost :29092


5 spring . kafka . producer . key . serializer = org . apache . kafka . common .
serialization . StringSerializer
spring . kafka . producer . value . serializer = org . springframework .
kafka . support . serializer . JsonSerializer

interval - in - cron = */10 * * * *

Рис.2.11. Alpha application.properties

Для генерации сообщений реализован класс производитель (рис. 2.12).


А для задания расписания генерации класс планировщика (рис.2.13) и в
основной класс приложения добавлена аннотация @EnableScheduling.
24

@Service
@RequiredArgsConstructor
public class AlphaKafkaProducer {
5
private final KafkaTemplate < String , MessageDto >
kafkaTemplate ;

private final String TOPIC_NAME = " beta - topic ";

10 private final Random random = new Random () ;


public void sendMessToBetaTopic () {
kafkaTemplate . send ( TOPIC_NAME , new MessageDto (0 L ,
/* т е м п е р а т у р а в г р а д у с а х Ц е л ь с и я */ -20 + random .
nextDouble () * (40 - ( -20) ) ,
/* д а в л е н и е в г е к т о п а с к а л я х */ 900 + random . nextDouble ()
* (1100 - 900) ,
15 /* в л а ж н о с т ь в п р о ц е н т а х */ random . nextDouble () * 100) ) ;
}

Рис.2.12. Класс Kafka производитель Alpha

@Component
@RequiredArgsConstructor
public class AlphaScheduler {
5 private final AlphaKafkaProducer producer ;

@Scheduled ( cron = " $ { interval - in - cron }")


public void scheduleBetaMess () {
producer . sendMessToBetaTopic () ;
10 }
}

Рис.2.13. Класс планировщик Alpha

2.4.2. Beta

Приложение beta реализует CRUD (см. Приложение 1), Kafka listener (рис.
2.15), отправку сообщения приложению gamma через feign client (рис. 2.16).
Для реализации данного функционала в файл конфигурации application.yml
должен содержать такие характеристики как: порт, на котором работает приложение
25

alpha, адрес и порт сервера Kafka, классы десериализаторов для ключей и значений
и данные для доступа к базе данных (рис. 2.14)

server :
port : 8080
spring :
5 datasource :
username : postgres
url : jdbc : postgresql :// localhost :5432/ postgres
password : postgres
kafka :
10 bootstrap - servers : localhost :29092 , localhost :29093
consumer :
group - id : app
auto - offset - reset : earliest
key - deserializer : org . apache . kafka . common . serialization .
StringDeserializer
15 value - deserializer : org . springframework . kafka . support .
serializer . JsonDeserializer
spring :
kafka :
consumer :
properties :
20 spring :
json :
trusted :
packages =*:

25 listener :
ack - mode : record

Рис.2.14. Конфигурация beta application.yml

2.4.3. Gamma

Приложение gamma аналогично приложению beta реализует CRUD, а также


еще один POST эндпоинт, отвечающий за обработку сообщений приходящих из
beta (рис. )
26

@Service
@RequiredArgsConstructor
@EnableKafka
5 public class BetaKafkaListener {

private final BetaRepository betaRepository ;

private final BetaFeignServiceUtil betaFeignServiceUtil ;


10 private final String TOPIC_NAME = " beta - topic ";

@KafkaListener ( topics = TOPIC_NAME )


public void msgListenerBeta ( BetaData record ) {
betaRepository . save ( record ) ;
15 betaFeignServiceUtil . whatIsTheWeatherNow ( record ) ;
}
}

Рис.2.15. Класс Kafka потребителя Beta

@FeignClient ( value = " BetaFeign " , url = " localhost :8086/ gamma
")
public interface BetaFeignServiceUtil {

5 @PostMapping ("/ weather - now ")


ResponseEntity < GammaDTO > whatIsTheWeatherNow ( BetaData
weather ) ;
}

Рис.2.16. Интерфейс Feign Client

@PostMapping ("/ weather - now ")


public ResponseEntity < GammaData > whatIsTheWeatherNow ( BetaDto
weather ) {

5 return ResponseEntity . ok ( gammaService . saveData ( new


GammaData (0 L , LocalDateTime . now () . toString () , "
temperature : " + weather . getTemperature () + " degrees
Celsius , pressure : " + weather . getPressure () + "
hectopascals , humidity : " + weather . getWetness () + "%")
));
}

Рис.2.17
27

2.5. Взаимодействие микросервисов

При инициализации системы взаимодействие между сервисами осуществля­


ется без ошибок и неполадок. Продеманстрировать корректность взаимодействия
можно с помощью Offset Explorer (рис. 2.18) и pgAdmin (рис. 2.19, 2.20).

Рис.2.18. Offset Explorer: сообщения присланные в beta-topic

Рис.2.19. pgAdmin: данные записанные в таблицу beta-data

Рис.2.20. pgAdmin: данные записанные в таблицу gamma-data


28

ЗАКЛЮЧЕНИЕ

В ходе проведения данной практики были изучены основные концепции и


принципы микросервисной архитектуры, а также различные способы взаимодей­
ствия между сервисами. Были освещены два важных инструмента для обеспечения
связи и передачи данных между сервисами – Apache Kafka и Feign Client.
Кроме того, были рассмотрены принципы архитектуры REST
(Representational State Transfer), которая является широко распространенным и
принятым подходом для проектирования веб-сервисов.
Также, были изучены основы контейнеризации приложений с использованием
Docker.
И полученные знания были применены на практике.
Таким образом, были решены следующие задачи:
1. Изучить необходимый теоретический материал для работы с указанными
ниже программными продуктами.
2. Реализовать демонстрационное приложение.
3. Продемонстрировать работу приложения.
Поставленная цель была достигнута. На мой взгляд, это очень интересный
учебный проект, который помог мне получить новый опыт и навыки работы с
инструментами, используемыми многими компаниями, в том числе Сбербанком, в
промышленной разработке.
29

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

1. Apache Kafka Documentation. — URL: https : / / kafka . apache . org /


documentation/ (дата обращения: 07.07.2023).
2. Apache Kafka: основы технологии. — URL: https://habr.com/ru/companies/
southbridge/articles/550934// (дата обращения: 07.07.2023).
3. Docker Documentation: Get sterted. — URL: https://docs.docker.com/get-
started/ (дата обращения: 07.07.2023).
4. Guide to Setting Up Apache Kafka Using Docker. — URL: https://www.
baeldung.com/ops/kafka-docker-setup (дата обращения: 07.07.2023).
5. Microservices. — URL: https://martinfowler.com/articles/microservices.html
(дата обращения: 07.07.2023).
6. REST with Spring. — URL: https://www.baeldung.com/rest-with-spring-series
(дата обращения: 07.07.2023).
7. Scheduling Tasks. — URL: https://spring.io/guides/gs/scheduling-tasks/ (дата
обращения: 07.07.2023).
8. Spring Boot Reference Documentation. — URL: https://docs.spring.io/spring-
boot/docs/current/reference/htmlsingle/ (дата обращения: 07.07.2023).
9. Spring Cloud OpenFeign. — URL: https : / / docs . spring . io / spring - cloud -
openfeign/docs/current/reference/html/ (дата обращения: 07.07.2023).
10. Spring Initializr. — URL: https://start.spring.io/ (дата обращения: 07.07.2023).
11. Что такое Docker и как его использовать в разработке. — URL: https:
//eternalhost.net/blog/razrabotka/chto-takoe-docker#p0 (дата обращения: 07.07.2023).
30

Приложение 1
Код контроллера Alpha

@RestController
@RequestMapping ( " / beta " )
@RequiredArgsConstructor
5 public class BetaController {

private final BetaService betaService ;

@GetMapping ( " / get - all " )


10 public ResponseEntity < List < BetaData > > findAllData () {

return ResponseEntity . ok ( betaService . findAll () ) ;


}

15 @GetMapping ( " / get - by - id /{ id } " )


public ResponseEntity < BetaData > findDataById ( @PathVariable
( " id " ) Long id ) {

try {
BetaData result = betaService . findById ( id ) ;
20 return new ResponseEntity < >( result , HttpStatus . OK )
;
} catch ( Exception e ) {
return new ResponseEntity < >( null , HttpStatus .
NOT_FOUND ) ;
}
}
25
@PostMapping ( " / save " )
public ResponseEntity < BetaData > saveData ( @RequestBody
BetaData data ) {

return ResponseEntity . ok ( betaService . saveData ( data ) ) ;


30 }

@PutMapping ( " / update " )


public ResponseEntity < BetaData > updateData ( @RequestBody
BetaData data ) {

35 return ResponseEntity . ok ( betaService . updateData ( data ) )


;
31

@DeleteMapping ( " / delete /{ id } " )


public ResponseEntity < HttpStatus > deleteData ( @PathVariable
( " id " ) Long id ) {
40
if ( betaService . deleteById ( id ) ) {
return new ResponseEntity < >( HttpStatus . OK ) ;
}
return new ResponseEntity < >( HttpStatus . NOT_FOUND ) ;
45 }
}

Вам также может понравиться