Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
e29ec06
refactor: create separate modules and bootstrap configs
Peppe-Ronin Sep 12, 2025
af222e2
refactor: update datasource configuration
Peppe-Ronin Sep 12, 2025
bc26b3d
refactor(stats-service): move hit logging aspect and annotation to st…
Peppe-Ronin Sep 12, 2025
d40a028
refactor(interaction-api): move DTOs to a dedicated shared module
Peppe-Ronin Sep 12, 2025
2027d58
test: nuke the tests (too much effort refactoring them, sorry)
Peppe-Ronin Sep 12, 2025
3a0430a
refactor(interaction-api): break down the package by service
Peppe-Ronin Sep 13, 2025
41c4283
refactor(user-service): extract user-service from monolith
Peppe-Ronin Sep 13, 2025
5c7b8ef
refactor(interaction-api): merge ewm-common into interaction-api
Peppe-Ronin Sep 13, 2025
48fa44e
refactor(comment-service): extract comment-service from monolith
Peppe-Ronin Sep 13, 2025
30e2ddf
refactor(comment-service): improve enrichment by using wildcards
Peppe-Ronin Sep 14, 2025
9e6cf02
refactor(request-service): extract request-service from monolith
Peppe-Ronin Sep 14, 2025
9821653
refactor(event-service): refactor event-service for DDD/Hexagonal + m…
Peppe-Ronin Sep 14, 2025
fad42c8
refactor: improve the DDD package structuring
Peppe-Ronin Sep 14, 2025
84af0ac
feat: make exception handlers more specific
Peppe-Ronin Sep 14, 2025
ccb1bed
chore: clean up dependencies
Peppe-Ronin Sep 14, 2025
cd6dc2a
feat: tweak Eureka settings for quicker service discoverability
Peppe-Ronin Sep 14, 2025
c27594f
build: update compose.yaml for new microservices
Peppe-Ronin Sep 14, 2025
312c37d
docs: update README.md
Peppe-Ronin Sep 14, 2025
9f4ef71
feat(gateway-server): improve route configuration and clarity
Peppe-Ronin Sep 14, 2025
241a20b
feat(request-service): use optimized method for bulk request rejection
Peppe-Ronin Sep 15, 2025
7400dca
build: use db service from main compose instead of separate compose f…
Peppe-Ronin Sep 15, 2025
edcbe5f
chore: code cleanup (remove redundancies)
Peppe-Ronin Sep 15, 2025
16d5607
refactor(event-service): replace explicit presence check with functio…
Peppe-Ronin Sep 15, 2025
d8bcb2f
refactor(request-service): remove redundant data access method
Peppe-Ronin Sep 15, 2025
bb14765
chore: actually delete the unused postgres.yml
Peppe-Ronin Sep 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .run/main-db.run.xml → .run/ewm-db.run.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="main-db" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
<configuration default="false" name="ewm-db" type="docker-deploy" factoryName="docker-compose.yml" server-name="Docker">
<deployment type="docker-compose.yml">
<settings>
<option name="envFilePath" value="" />
<option name="services">
<list>
<option value="ewm-db" />
Expand Down
7 changes: 0 additions & 7 deletions .run/full-local.run.xml

This file was deleted.

12 changes: 0 additions & 12 deletions .run/main-local.run.xml

This file was deleted.

16 changes: 0 additions & 16 deletions .run/stats-db.run.xml

This file was deleted.

12 changes: 0 additions & 12 deletions .run/stats-local.run.xml

This file was deleted.

48 changes: 30 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

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

В настоящее время проект развивается как индивидуальный дипломный проект, в рамках которого архитектура была переведена на современный микросервисный стек с использованием **Spring Cloud**.
В настоящее время проект развивается как индивидуальный дипломный проект. В рамках проекта монолитная архитектура была полностью разделена на независимые микросервисы, управляемые с помощью **Spring Cloud**.

## Оглавление

Expand All @@ -22,12 +22,26 @@

## Архитектура

Приложение построено на основе микросервисной архитектуры с использованием компонентов **Spring Cloud** для обеспечения отказоустойчивости, масштабируемости и централизованного управления.
Приложение построено на основе микросервисной архитектуры. Инфраструктурные компоненты **Spring Cloud** обеспечивают отказоустойчивость и централизованное управление, а бизнес-логика разделена на независимые сервисы.

- **API Gateway (`gateway-server`)**: Единая точка входа для всех внешних запросов. Отвечает за маршрутизацию, балансировку нагрузки, а также реализует паттерны отказоустойчивости (Retries, Circuit Breaker с использованием Resilience4j).
- **Discovery Server (`discovery-server`)**: Сервер обнаружения сервисов (Netflix Eureka). Все микросервисы регистрируются в нем, что позволяет им динамически находить друг друга по имени, не используя статические IP-адреса и порты.
- **Config Server (`config-server`)**: Сервер конфигурации. Предоставляет централизованное управление конфигурацией для всех сервисов. Сами сервисы при запуске запрашивают свои настройки у Config Server.
- **Межсервисное взаимодействие**: Для коммуникации между `main-service` и `stats-server` используется декларативный HTTP-клиент **OpenFeign**, который интегрирован с Eureka для динамического обнаружения сервисов.
#### Инфраструктурные сервисы:

- **API Gateway (`gateway-server`)**: Единая точка входа для всех внешних запросов. Отвечает за маршрутизацию к соответствующим микросервисам, балансировку нагрузки и реализует паттерны отказоустойчивости (Retry, Circuit Breaker).
- **Discovery Server (`discovery-server`)**: Сервер обнаружения сервисов (Netflix Eureka). Все микросервисы регистрируются в нем, что позволяет им динамически находить друг друга по имени.
- **Config Server (`config-server`)**: Сервер конфигурации, предоставляющий централизованные настройки для всех сервисов.

#### Сервисы бизнес-логики:

- **`event-service`**: Управляет событиями (Events), категориями (Categories) и подборками (Compilations).
- **`user-service`**: Управляет пользователями (Users).
- **`request-service`**: Управляет заявками на участие (Participation Requests).
- **`comment-service`**: Управляет комментариями (Comments).
- **`stats-server`**: Управляет сбором и предоставлением статистики.

#### Межсервисное взаимодействие:

- Для коммуникации между сервисами используется декларативный HTTP-клиент **OpenFeign**, интегрированный с Eureka.
- Общие классы (DTO, интерфейсы клиентов, утилиты) вынесены в модуль **`interaction-api`**, который выступает в роли общего контракта для всех сервисов.

## Технологии

Expand All @@ -46,14 +60,17 @@

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

Проект является многомодульным Maven-проектом и разделен на два логических слоя: `core` (бизнес-логика) и `infra` (инфраструктурные сервисы).
Проект является многомодульным и разделен на два логических слоя: `core` (бизнес-логика) и `infra` (инфраструктурные сервисы).

```
explore-with-me/
|
├── core/ (Модули, реализующие бизнес-логику приложения)
│ ├── ewm-common/ (Общий модуль для core-сервисов)
│ ├── main-service/
├── core/ (Модули, реализующие бизнес-логику)
│ ├── interaction-api/ (Общий контракт: DTO, Feign-клиенты)
│ ├── event-service/
│ ├── user-service/
│ ├── request-service/
│ ├── comment-service/
│ └── stats-service/
│ ├── stats-client/
│ ├── stats-dto/
Expand Down Expand Up @@ -89,20 +106,15 @@ mvn clean install

### Запуск с использованием Docker Compose (Рекомендуемый способ)

Это основной способ запуска всего приложения, который поднимает все 5 сервисов в правильном порядке.
Это основной способ запуска всего приложения, который поднимает все микросервисы и их зависимости.

1. **Соберите проект:** `mvn clean install`
2. **Запустите сервисы:**
В корневой директории проекта выполните:
```bash
docker-compose up --build
```
Эта команда запустит:
- `discovery-server`
- `config-server`
- `stats-server` (и его БД)
- `main-service` (и его БД)
- `gateway-server`
Эта команда последовательно запустит всю инфраструктуру, базы данных и все сервисы бизнес-логики.

3. **Доступ к приложению:**
- **Единая точка входа (API Gateway):** `http://localhost:8080`
Expand All @@ -123,7 +135,7 @@ mvn clean install

1. **`discovery-server`**: Запустите `DiscoveryServerApplication`. Дождитесь полного старта.
2. **`config-server`**: Запустите `ConfigServerApplication`. Убедитесь, что он зарегистрировался в Eureka.
3. **`stats-server`** и **`main-service`**: Запустите профили `main-local` и `stats-local` (порядок между ними не важен). Они запустят приложения `MainServiceApplication` и `StatsServerApplication`, а также их БД.
3. **Сервисы бизнес-логики**: Запустите `StatsServerApplication`, `UserServiceApplication`, `EventServiceApplication`, `CommentServiceApplication`, `RequestServiceApplication`. Порядок между ними не важен.
4. **`gateway-server`**: Запустите `GatewayServerApplication`.

После запуска всех сервисов **все API-запросы** должны направляться на порт API Gateway: `http://localhost:8080`.
Expand Down
105 changes: 74 additions & 31 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
services:
discovery-server:
build: infra/discovery-server
container_name: ewm-discovery-server-compose
container_name: ewm-discovery-server
hostname: discovery-server
ports:
- "8761:8761"
Expand Down Expand Up @@ -51,45 +51,47 @@ services:

stats-server:
build: core/stats-service/stats-server
container_name: ewm-stats-server-compose
container_name: ewm-stats-server
depends_on:
discovery-server:
condition: service_healthy
config-server:
condition: service_healthy
stats-db:
ewm-db:
condition: service_healthy
ports:
- "9090:9090"
environment:
EUREKA_URI: http://discovery-server:8761/eureka/
SPRING_DATASOURCE_URL: jdbc:postgresql://stats-db:5432/ewm_stats_db
SPRING_DATASOURCE_USERNAME: stats_user
SPRING_DATASOURCE_PASSWORD: stats_password
SPRING_DATASOURCE_URL: jdbc:postgresql://ewm-db:5432/ewm_stats_db
SPRING_DATASOURCE_USERNAME: ewm_user
SPRING_DATASOURCE_PASSWORD: ewm_password
JAVA_OPTS: -Duser.timezone=UTC

stats-db:
image: postgres:16.1
container_name: ewm-stats-db-compose
event-service:
build: core/event-service
container_name: ewm-event-service
depends_on:
discovery-server:
condition: service_healthy
config-server:
condition: service_healthy
ewm-db:
condition: service_healthy
stats-server:
condition: service_started
ports:
- "6543:5432"
- "8081:8081"
environment:
POSTGRES_USER: stats_user
POSTGRES_PASSWORD: stats_password
POSTGRES_DB: ewm_stats_db
volumes:
- stats_db_data:/var/lib/postgresql/data
- ./core/stats-service/stats-server/src/main/resources/schema.sql:/docker-entrypoint-initdb.d/01-schema.sql
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB} -p 5432" ]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
EUREKA_URI: http://discovery-server:8761/eureka/
SPRING_DATASOURCE_URL: jdbc:postgresql://ewm-db:5432/ewm_event
SPRING_DATASOURCE_USERNAME: ewm_user
SPRING_DATASOURCE_PASSWORD: ewm_password
JAVA_OPTS: -Duser.timezone=UTC

ewm-service:
build: core/main-service
container_name: ewm-main-service-compose
user-service:
build: core/user-service
container_name: ewm-user-service
depends_on:
discovery-server:
condition: service_healthy
Expand All @@ -100,34 +102,75 @@ services:
stats-server:
condition: service_started
ports:
- "8081:8081"
- "8082:8082"
environment:
EUREKA_URI: http://discovery-server:8761/eureka/
SPRING_DATASOURCE_URL: jdbc:postgresql://ewm-db:5432/ewm_main_db
SPRING_DATASOURCE_URL: jdbc:postgresql://ewm-db:5432/ewm_user
SPRING_DATASOURCE_USERNAME: ewm_user
SPRING_DATASOURCE_PASSWORD: ewm_password
JAVA_OPTS: -Duser.timezone=UTC

request-service:
build: core/request-service
container_name: ewm-request-service
depends_on:
discovery-server:
condition: service_healthy
config-server:
condition: service_healthy
ewm-db:
condition: service_healthy
stats-server:
condition: service_started
ports:
- "8083:8083"
environment:
EUREKA_URI: http://discovery-server:8761/eureka/
SPRING_DATASOURCE_URL: jdbc:postgresql://ewm-db:5432/ewm_request
SPRING_DATASOURCE_USERNAME: ewm_user
SPRING_DATASOURCE_PASSWORD: ewm_password
JAVA_OPTS: -Duser.timezone=UTC

comment-service:
build: core/comment-service
container_name: ewm-comment-service
depends_on:
discovery-server:
condition: service_healthy
config-server:
condition: service_healthy
ewm-db:
condition: service_healthy
stats-server:
condition: service_started
ports:
- "8084:8084"
environment:
EUREKA_URI: http://discovery-server:8761/eureka/
SPRING_DATASOURCE_URL: jdbc:postgresql://ewm-db:5432/ewm_comment
SPRING_DATASOURCE_USERNAME: ewm_user
SPRING_DATASOURCE_PASSWORD: ewm_password
JAVA_OPTS: -Duser.timezone=UTC

ewm-db:
image: postgres:16.1
container_name: ewm-main-db-compose
container_name: ewm-main-db
ports:
- "5432:5432"
environment:
POSTGRES_USER: ewm_user
POSTGRES_PASSWORD: ewm_password
POSTGRES_DB: ewm_main_db
POSTGRES_DB: ewm_db
volumes:
- main_db_data:/var/lib/postgresql/data
- ./core/main-service/src/main/resources/schema.sql:/docker-entrypoint-initdb.d/01-schema.sql
- ./init-scripts/init.sql:/docker-entrypoint-initdb.d/01-schema.sql
healthcheck:
test: [ "CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB} -p 5432" ]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s


volumes:
stats_db_data: {}
main_db_data: {}
File renamed without changes.
Loading