Ревью микросервисного проекта "Планировщик задач" на Java от студента @immagixe

YOUTUBE · 18.11.2025 19:17

Ключевые темы и таймкоды

Введение и цель проекта

0:02
  • Проект реализован Максимом, но не полностью.
  • Цель проекта - практиковать микросервисную архитектуру.
  • Проект - планировщик задач, реализованный в виде 4 микросервисов.

Структура проекта

1:02
  • Проект состоит из 7 микросервисов, 3 из которых взяты из готовых образов, 4 написаны самостоятельно.
  • Фронтенд - одностраничное приложение, взаимодействующее с бэкендом через REST API.
  • Бэкенд хранит данные в SQL и сессии в Redis.

Функционал микросервисов

1:58
  • Планировщик задач отправляет пользователям статистику по их задачам.
  • Email Sender обрабатывает задачи для рассылки писем.
  • REST API отправляет приветственные письма при регистрации пользователя.

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

3:54
  • Взаимодействие происходит через RabbitMQ.
  • Максим реализовал REST API на Java Spring Boot и Email Sender на Kotlin Spring Boot.
  • Фронтенд не реализован, но планируется на основе Engine X.

Цели проекта

4:51
  • Цель проекта - разобраться в микросервисной архитектуре и написании Docker Compose.
  • Вторая цель - проявить инициативу в проектировании и дизайне.
  • Студент должен был самостоятельно разработать дизайн SQL базы данных и методов для создания, редактирования и удаления задач.

Функционал проекта

5:50
  • Проект аналогичен упрощенному аналогу Trello.
  • Пользователи могут регистрироваться, логиниться, создавать, редактировать и удалять задачи.
  • Планировщик собирает статистику по задачам и отправляет отчеты на email.

Дизайн базы данных

6:49
  • База данных состоит из двух таблиц: пользователи и задачи.
  • В таблице пользователей поле "роль" лишнее, его следует убрать.
  • В таблице задач поле "status" следует переименовать в "completed" или добавить дополнительные статусы.

Технические проблемы

11:44
  • В таблице пользователей нет уникального индекса на поле email.
  • Нет индекса на поле email, что замедляет поиск пользователей.
  • В таблице задач нет индекса на поле user_id, что также замедляет поиск задач.

Демонстрация работы

14:41
  • В проекте нет фронтенда, но есть автоматически сгенерированная документация по REST методам.
  • Методы регистрации и получения информации о задачах можно протестировать через документацию.
  • Реализация сессий не соответствует ТЗ.

Авторизация и задачи

16:40
  • Токены используются для авторизации вместо передачи логина и пароля.
  • Метод tasks возвращает список задач текущего пользователя.
  • Методы позволяют создавать, удалять и редактировать задачи.

Проверка доступа и сущностей

17:39
  • Проверка доступа предотвращает удаление или редактирование задач невладеющим пользователем.
  • Проверка на существование сущностей предотвращает ошибки 404.

Проблемы с сессиями и Basic Auth

19:38
  • Basic Auth не хранит сессии, что делает Redis бесполезным.
  • Сессии имеют время экспирации и более безопасны, так как не передают пароли.
  • Рекомендуется использовать сессии или токены для авторизации.

Частичное обновление сущностей

21:37
  • Метод patch не поддерживает частичное обновление задач.
  • Частичное обновление должно быть реализовано для корректной работы метода patch.

Перегруппировка методов

23:33
  • Методы сгруппированы неструктурированно, рекомендуется разбить на части.
  • Важно соблюдать принципы REST, например, разные методы для разных действий над одной сущностью.

Адрес запросов и множественное число

26:26
  • Адрес запроса для создания задачи через POST нарушает принцип REST.
  • Рекомендуется использовать POST для создания одной задачи, а не множественного числа.

Моно репозиторий vs отдельные репозитории

29:22
  • Моно репозиторий упрощает управление, но имеет единую историю для всех сервисов.
  • Отдельные репозитории чище, но требуют управления и могут иметь дублирование кода.

Общий код и зависимости

31:18
  • Проекты могут иметь общий код, который можно копировать или выносить в зависимости.
  • Копирование кода проще, но может быть избыточным.
  • Вынос кода в зависимости предотвращает дублирование, но усложняет управление зависимостями.

Артефактор и зависимости

33:14
  • В рамках Пэт проекта копирование кода приемлемо, но в рабочем проекте лучше выносить зависимости в отдельные модули.
  • В рабочем проекте зависимости собираются и подключаются к микросервисам.

Docker Compose и автоматизация

34:14
  • Реализованы три Docker Compose стека: для запуска сервисов, сборки образов и запуска на удаленном сервере.
  • Автоматизация с помощью Diploid для обновления стека при пуше.

Безопасность и пароли

35:12
  • Отсутствие паролей для RabbitMQ и Redis может быть опасным.
  • Рекомендуется использовать пароли для управления секретами и конфигурирования сервисов в разных условиях.

Оптимизация сборки

37:03
  • Оптимизация скорости сборки через копирование только XML, скачивание зависимостей и копирование исходников.
  • Итоговый образ может быть больше, чем нужно, рекомендуется собирать JAR в образе и использовать SlimJAR для уменьшения размера.

Проблемы с регистрацией пользователей

39:01
  • Отсутствие ограничения уникальности для email может привести к созданию двух пользователей с одним email.
  • Рекомендуется добавить ограничение уникальности или использовать транзакции для гарантированной атомарности.

Дизайн и паттерны

42:55
  • Интерфейс Email Creator можно переработать в Email Factory для более структурированного кода.
  • Рекомендуется удалять ненужный код для улучшения читаемости и модификации.

Модель User

45:49
  • Модель User используется для JPA и валидации, что создает проблемы.
  • Рекомендуется разделить модель на две части: User для JPA и UserDTO для валидации.

Сервис Users

47:46
  • Сервис Users смешивает бизнес-логику и REST-логику, что ограничивает его применение в будущем.
  • Рекомендуется отделить бизнес-логику от REST-логики, используя кастомные исключения и контроллеры.

Сервис для работы с задачами

50:37
  • Сервис принимает команды от контроллера и выполняет операции над репозиторием.
  • Методы "сейв" и "апдейт" выполняют одинаковые действия, можно оставить только "сейв".
  • Смешивание бизнес-логики и R3P, лучше использовать контроллер для обработки ответов.

Контроллер для работы с задачами

51:34
  • Пересмотреть структуру методов, чтобы ID передавались в теле.
  • Оптимизировать вызов проверки авторизации, возможно, использовать фильтр или аннотацию.

Планировщик

52:33
  • Планировщик собирает статистику по задачам, формирует отчеты и отправляет их через RabbitMQ.
  • Нет простого способа изменить расписание, предлагается использовать переменную окружения.
  • Класс "UserTask" используется как общий предок, но его полезность под вопросом.

Отправка email через RabbitMQ

56:28
  • Планировщик собирает все email пользователей в одну коллекцию и отправляет через RabbitMQ.
  • Рекомендуется формировать отдельные сообщения для каждого пользователя для лучшей оптимизации.

Сервис для отправки email

1:00:24
  • Сервис получает сообщения из очереди и отправляет их с помощью Spring Mail.
  • Логика элементарная, но ручная реализация может быть улучшена.
  • Создание объектов RabbitMQ не должно быть задачей этого сервиса, лучше перенести это в планировщик или R3P.

Итоги проекта

1:03:15
  • Реализована Continuous Delivery с помощью GitHub Actions.
  • Проект легко запускается и тестируется, удобно использовать Swagger.
  • Достигнуты цели по практике с микросервисами и проявлению инициатив в дизайне.
  • Есть огрехи в функционале и коде, но это можно исправить при большем времени на проект.