Skip to content

About

Микросервисная архитектура "Яндекс"

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Explore With Me (EWM)

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

Проект построен как набор Spring Boot микросервисов, взаимодействующих через REST, gRPC и Apache Kafka, с централизованным Service Discovery и Config Server.

Команда проекта

Архитектура

Приложение разбито на три группы сервисов:

Инфраструктурные сервисы (infra)

Сервис Назначение
discovery-server Service Discovery на базе Netflix Eureka — регистрация и обнаружение всех остальных сервисов
config-server Централизованное хранение конфигурации (Spring Cloud Config)
gateway-server Единая точка входа, маршрутизация запросов к core-сервисам

Основные сервисы (core)

Сервис Назначение
user-service Управление пользователями
category-service Управление категориями мероприятий
event-service Мероприятия, подборки (compilations), публичный/приватный/административный API
request-service Заявки на участие в мероприятиях
comment-service Комментарии к опубликованным мероприятиям

Сервисы рекомендательной системы (stats)

Сервис Назначение
collector Принимает действия пользователей (просмотр/заявка/лайк) по gRPC, публикует их в Kafka в формате Avro
aggregator Читает поток действий из Kafka, рассчитывает коэффициент косинусного сходства мероприятий, публикует результат в Kafka
analyzer Хранит историю взаимодействий и коэффициенты сходства в PostgreSQL, отдаёт рекомендации по gRPC
stats-server Классический сервис статистики посещений (сохранён с первого этапа)

Внутренние gRPC-клиенты для Collector и Analyzer вынесены в отдельный модуль stats-client, контракты — в stats-proto (Protobuf) и stats-dto (Avro-схемы).

Этапы разработки

Этап 1: Сервис статистики (Stats Service)

Реализована инфраструктура для сбора и анализа данных о посещаемости ресурсов: хранилище хитов по эндпоинтам, расчёт уникальных просмотров по IP, агрегация за произвольный период, HTTP-клиент для интеграции со сновным сервисом.

Этап 2: Основной сервис (Main Service)

Реализована вся бизнес-логика согласно спецификации API:

  • Публичный API — поиск мероприятий с динамической фильтрацией (QueryDSL).
  • Приватный API — управление своими мероприятиями, участие в чужих, подтверждение заявок.
  • Административный API — модерация контента, справочники категорий и пользователей.
  • Многоуровневая валидация бизнес-правил (временные интервалы, лимиты участия, статусы модерации).

Этап 3: Комментарии

Добавлена система комментариев к опубликованным мероприятиям.

  • Статусы модерации: PENDING, PUBLISHED, REJECTED.
  • Проверка владения — редактировать комментарий может только автор.
  • FetchType.LAZY и отсутствие рекурсивных связей в сущностях для производительности БД.

Этап 4: Микросервисная архитектура и рекомендательная система

Проект переведён на микросервисную архитектуру: каждый core-модуль выделен в отдельный Spring Boot сервис, добавлены Eureka и Config Server, взаимодействие между сервисами через Feign/gRPC-клиенты вместо прямых вызовов.

Реализована рекомендательная система из трёх сервисов:

  • Collector принимает действия пользователей по gRPC (ACTION_VIEW, ACTION_REGISTER, ACTION_LIKE) и пишет их в топик Kafka stats.user-actions.v1 в формате Avro.
  • Aggregator инкрементально пересчитывает косинусное сходство мероприятий при каждом новом действии, не пересчитывая с нуля — обновляются только частичные суммы весов и суммы минимальных весов пар мероприятий. Результат публикуется в топик stats.events-similarity.v1.
  • Analyzer строит на основе накопленных данных персональные рекомендации по трём алгоритмам: похожие мероприятия, предсказание оценки методом ближайших соседей, сумма весов взаимодействий (для рейтинга мероприятия).

event-service теперь запрашивает рейтинг мероприятия и рекомендации через gRPC-клиент к Analyzer вместо статичного счётчика просмотров; request-service отправляет события о регистрации на мероприятие в Collector.

Технологический стек

Категория Технологии
Язык разработки Java 21
Фреймворк Spring Boot, Spring Cloud (Eureka, Config, Gateway)
Межсервисное взаимодействие REST, gRPC (Protobuf), Apache Kafka (Avro)
Сборка проекта Maven (multi-module)
База данных PostgreSQL (отдельная БД на каждый сервис)
Работа с данными Spring Data JPA, QueryDSL
Маппинг и генерация кода MapStruct, Lombok
Контейнеризация Docker, Docker Compose

Запуск проекта

mvn clean package
docker-compose up --build

После старта:

  • Eureka Dashboard — http://localhost:8761
  • Config Server — http://localhost:8888
  • Gateway — http://localhost:8080
  • Stats-сервисы: Collector (8088), Aggregator (8089), Analyzer (8090)

Спецификации API — ewm-main-service-spec.json и ewm-stats-service-spec.json в корне репозитория.

Спецификация API

Мероприятия, категории, пользователи, заявки

Полный список эндпоинтов — в ewm-main-service-spec.json. Публичный API поддерживает поиск и фильтрацию мероприятий, приватный — управление своими мероприятиями и заявками, административный — модерацию и справочники.

Дополнительно у мероприятия появились:

  • GET /events/recommendations — рекомендации мероприятий для пользователя (заголовок X-EWM-USER-ID).
  • PUT /events/{eventId}/like — лайк посещённого мероприятия (400, если пользователь не был на мероприятии).

Комментарии

Административный API

  • GET /admin/comments — поиск с фильтрацией (текст, авторы, событие, статус, диапазон дат, пагинация).
  • PATCH /admin/comments/{commentId} — изменение статуса модерации.
  • DELETE /admin/comments/{commentId} — удаление любого комментария.

Публичный API

  • GET /comments — поиск опубликованных комментариев с фильтрацией и сортировкой по дате.
  • GET /comments/{commentId} — получение опубликованного комментария.

Приватный API

  • POST /users/{userId}/events/{eventId}/comment — добавить комментарий к опубликованному мероприятию.
  • GET /users/{userId}/comments — все комментарии пользователя.
  • GET /users/{userId}/events/{eventId}/comments — комментарии пользователя к конкретному мероприятию.
  • GET /users/{userId}/comments/{commentId} — комментарий пользователя по идентификатору.
  • PATCH /users/{userId}/comments/{commentId} — редактирование своего комментария.
  • DELETE /users/{userId}/comments/{commentId} — удаление своего комментария.

Рекомендательный сервис (gRPC)

Collector — stats.service.collector.UserActionController

  • CollectUserAction — приём действия пользователя (просмотр, заявка, лайк).

Analyzer — stats.service.dashboard.RecommendationsController

  • GetRecommendationsForUser — поток рекомендованных мероприятий с предсказанной оценкой.
  • GetSimilarEvents — поток мероприятий, похожих на указанное, с которыми пользователь ещё не взаимодействовал.
  • GetInteractionsCount — суммарный вес взаимодействий по списку мероприятий (используется для рейтинга).

About

Микросервисная архитектура "Яндекс"

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages