Перейти к основному содержимому

Первые шаги к микросервисам

Разработчику Архитектору Инженеру

Здесь — практикум: из трёх небольших сервисов на разных языках собирается цепочка "принять заказ → обработать → уведомить клиента". Это учебный стенд — в продакшене так же начинают с одного сценария, а затем выносят пароли в секреты, разделяют базы и добавляют мониторинг. Теория MSA и масштабирования — в архитектуре микросервисов и масштабировании; контракты и типы обмена — в коммуникации и интеграции.


Первые шаги к микросервисам

Микросервисная архитектура — подход, при котором приложение строится как набор небольших, независимо разворачиваемых сервисов.

Каждый сервис отвечает за одну конкретную бизнес-функцию и общается с другими сервисами через чётко определённые интерфейсы (REST, очереди, gRPC).

Такой подход позволяет масштабировать отдельные части системы, обновлять стек по сервису (Python здесь, Java там) и ограничивать blast radius при сбое одного компонента.

Рассмотрим практический пример создания распределённой системы обработки заявок.

Система будет состоять из трех основных компонентов:

  • сервиса приема заявок на Python,
  • сервиса обработки заказов на Java,
  • сервиса уведомлений на C#.

Все компоненты будут взаимодействовать через REST API для синхронных запросов (синхронная коммуникация) и RabbitMQ для асинхронного обмена сообщениями (асинхронная коммуникация, RabbitMQ). В качестве хранилища данных выступит база PostgreSQL (SQL).


Сценарий сквозь систему

  1. Клиент отправляет POST /orders на Python-сервис (порт 8001) с номером заказа и суммой.
  2. Сервис валидирует данные, пишет строку в PostgreSQL со статусом pending, отвечает 201 с id заказа.
  3. В фоне в очередь order_events уходит сообщение order.created.
  4. Java-сервис по расписанию или по событию читает pending-заказы, переводит в processingcompleted, снова публикует в очередь.
  5. C#-сервис читает очередь и шлёт уведомление (в демо — HTTP на callback).

Так клиент получает быстрый ответ, а тяжёлая работа и уведомления не блокируют HTTP-поток — типичный гибрид sync + async, описанный в типах взаимодействия.


Архитектура системы

Система состоит из четырех ключевых элементов.

Первый элемент — это клиентское приложение или внешний источник, который инициирует создание заявки.

Второй элементсервис приема заявок (Order Ingestion Service), написанный на Python. Этот компонент принимает входящие данные, валидирует их и сохраняет информацию в базу данных.

Третий элементсервис обработки заказов (Order Processing Service), реализованный на Java. Он читает новые заявки из базы данных, выполняет бизнес-логику и формирует задачи для дальнейшей обработки.

Четвертый элементсервис уведомлений (Notification Service) на C#, который получает события о статусе заказа через брокер сообщений и отправляет уведомления пользователям.

Взаимодействие между компонентами происходит по двум каналам.

Синхронный канал использует REST API для немедленного ответа на запросы.

Асинхронный канал использует RabbitMQ для передачи событий, когда требуется фоновая обработка без блокировки основного потока выполнения.

База данных PostgreSQL служит единым источником истины для хранения структуры заявок и истории их изменений.

Play ITЗагрузка интерактивного демо…


Техническая сводка

КомпонентКоманда запускаПорт (API)Описание функции
Docker (База данных PostgreSQL + Брокер RabbitMQ)docker-compose up -d5432, 15672Запуск инфраструктуры. Порт 5432 обеспечивает подключение к базе данных, порт 15672 предоставляет веб-интерфейс для мониторинга очередей и сообщений брокера.
Python (Сервис приема заявок)uvicorn main:app --reload --host 0.0.0.0 --port 80018001Принимает входящие запросы на создание заказов через REST API, сохраняет данные в базу и отправляет событие о создании заказа в очередь RabbitMQ. Документация API доступна по адресу http://localhost:8001/docs.
Java (Сервис обработки заказов)mvn spring-boot:run8082Читает заказы со статусом "pending" из базы данных, выполняет бизнес-логику обработки, обновляет статус заказа и публикует событие о завершении работы в очередь RabbitMQ.
C# (Сервис уведомлений)dotnet run5000 или 5001Подписывается на очередь RabbitMQ, получает события об изменении статуса заказа и инициирует отправку уведомления клиенту через HTTP-запрос. Сервис автоматически начинает прослушивание при запуске приложения.

Подготовка инфраструктуры

Первый этап работы требует наличия специализированного программного обеспечения для управления контейнерами и сред выполнения языков программирования. Отсутствие этих инструментов делает запуск проекта невозможным.

Элемент проверкиСтатусПримечание
1Установлен Docker и Docker Composeсм. блок проверки ниже
2Установлен Python 3.9+см. блок проверки ниже
3Установлена JDK 17+см. блок проверки ниже
4Установлена платформа .NET 6+см. блок проверки ниже
5Запущены контейнеры БД и брокераdocker compose up -d, статус Up
6Проверена связность с сетевыми службамиping / telnet к портам 5432 и 5672 в сети Docker

Проверка окружения:

docker --version
docker compose version
python --version
java -version
dotnet --version
docker compose up -d
docker compose ps

Разбор:

  • Строки с --version / -version проверяют, что CLI Docker, Python, Java и .NET установлены и доступны в PATH перед запуском стенда.
  • docker compose up -d поднимает PostgreSQL, RabbitMQ и другие зависимости в фоне; ps показывает, что контейнеры в статусе Up. Шаблоны compose для Postgres и app+db — Docker Compose — готовые стеки.

Настройка среды разработки

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

Основными требованиями являются наличие Docker для запуска контейнеров с базой данных и брокером сообщений, а также установленные языки программирования Python 3.9+, Java 17+ и .NET 6+.

База данных PostgreSQL должна быть доступна для подключения по стандартному порту 5432.

Брокер сообщений RabbitMQ должен быть запущен на порту 5672 для AMQP протокола и иметь веб-интерфейс на порту 15672.

Перед началом работы создайте директорию проекта microservices-demo и внутри нее поддиректории для каждого сервиса — order-ingestion, order-processing, notifications.

Также создайте файл docker-compose.yml для оркестрации зависимостей.

Файл конфигурации Docker Compose определяет три службы:

  • базу данных PostgreSQL,
  • брокер RabbitMQ,
  • пользовательские сервисы.

Каждая служба имеет свои параметры подключения, переменные окружения и тома для хранения данных. Базовые стеки "только Postgres" и "app + db + Redis" с построчным разбором — Docker Compose — готовые стеки (№3–5); Dockerfile для API — галерея Lab; теория ключей — docker-compose.

Код ITЗагрузка примера кода…

Разбор:

  • Секция services описывает контейнеры — image — образ, environment — логин/пароль и имя БД, ports пробрасывает порты на хост.
  • networks связывает сервисы в одну Docker-сеть — внутри неё хост postgres и rabbitmq резолвится по имени сервиса.
  • volumes для PostgreSQL сохраняет данные на диске хоста, чтобы перезапуск контейнера не обнулял таблицы заказов.

Создание сети microservices-net обеспечивает изолированное взаимодействие между контейнерами.

Использование томов для PostgreSQL гарантирует сохранность данных после перезапуска контейнера. Веб-интерфейс RabbitMQ позволяет визуализировать очереди, обмены и состояние сообщений.

Сервис приема заявок требует изолированного пространства зависимостей. Создание виртуального окружения предотвращает конфликты версий библиотек с системными пакетами.

  • Создание и активация venv в каталоге order-ingestion:
python -m venv venv # Windows: py -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt

Разбор:

  • Пакеты ставятся в активированное venv — FastAPI — HTTP API, SQLAlchemy — ORM, psycopg2 — драйвер PostgreSQL, pika — клиент AMQP.
  • python -m venv создаёт изолированное окружение; activate переключает shell на него, чтобы pip не трогал системный Python.
  • Установка зависимостей: при отсутствии requirements.txt — см. блок pip install в разделе "Сервис приема заявок на Python" ниже.
  • Проверка: Убедитесь, что импорты модулей в коде не вызывают ошибок ModuleNotFoundError.

Проект на базе Spring Boot управляется сборщиком Maven. Процесс сборки включает скачивание всех необходимых библиотек и компиляцию исходного кода.

  • Инициализация проекта: Перейдите в директорию сервиса order-processing.
  • Сборка в каталоге order-processing:
mvn clean compile
mvn package

Разбор:

  • mvn clean compile пересобирает исходники с нуля; mvn package собирает JAR в target/ для деплоя или запуска.
  • Зависимости: Убедитесь, что в папке target появился файл архива. Проверьте логи Maven на отсутствие ошибок разрешения зависимостей (Dependency Resolution Error).
  • Конфигурация: Файл application.properties должен содержать правильные параметры подключения к базе данных postgres и брокеру rabbitmq внутри сети Docker.

Сервис уведомлений использует экосистему .NET. Восстановление пакетов NuGet обеспечивает наличие всех необходимых библиотек для работы с очередями и HTTP-клиентами.

  • Восстановление и сборка в каталоге notifications:
dotnet restore
dotnet build

Разбор:

  • dotnet restore скачивает NuGet-пакеты; dotnet build проверяет, что проект notification-сервиса компилируется без ошибок.
  • Проверка: Убедитесь, что проект собирается без ошибок. В случае использования современных фреймворков убедитесь в наличии нужных версий пакетов RabbitMQ.Client и Microsoft.AspNetCore.Mvc.NewtonsoftJson.

Сервис приема заявок на Python

Сервис приема заявок отвечает за получение данных от клиентов, валидацию входных параметров и сохранение информации в базу данных.

Для реализации используется фреймворк FastAPI, который обеспечивает высокую производительность и автоматическую генерацию документации API.

Библиотека SQLAlchemy используется для работы с базой данных через ORM.

Установите необходимые зависимости в виртуальном окружении Python:

pip install fastapi uvicorn sqlalchemy psycopg2-binary pydantic

Разбор:

  • uvicorn main:app запускает ASGI-приложение FastAPI: main — модуль, app — объект приложения; --reload перезагружает код при правках.
  • Пакеты ставятся в активированное venv — FastAPI — HTTP API, SQLAlchemy — ORM, psycopg2 — драйвер PostgreSQL, pika — клиент AMQP.

Структура проекта включает:

  • модуль main.py с точкой входа,
  • модуль database.py для настройки подключения к базе данных,
  • модуль models.py с описанием схем таблиц,
  • модуль schemas.py с моделями данных Pydantic для валидации входящих запросов.

Файл database.py содержит функцию создания сессии и объект Base для декларативного определения моделей.

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

Код ITЗагрузка примера кода…

Разбор:

  • create_engine(DATABASE_URL) открывает пул соединений к PostgreSQL; URL содержит логин, пароль, хост postgres и имя БД.
  • sessionmaker фабрикует сессии ORM; get_db() с yield отдаёт сессию в обработчик FastAPI и закрывает её в finally.
  • Base = declarative_base() — базовый класс для моделей таблиц; Base.metadata.create_all создаёт таблицы при старте (в проде чаще миграции).

Модель Order описывает структуру таблицы в базе данных.

Поля включают:

  • уникальный идентификатор,
  • номер заказа,
  • статус,
  • сумму,
  • дату создания.

Индексы на полях номера заказа и статуса ускоряют поиск записей.

Код ITЗагрузка примера кода…

Разбор:

  • __tablename__ связывает класс с таблицей orders; Column задаёт тип SQL, primary_key, index, nullable.
  • default="pending" проставляет начальный статус заказа; составной Index ускоряет выборку по полю status.
  • SQLAlchemy создаст таблицу orders при create_all; уникальный order_number не даст вставить дубликат на уровне БД.

Модель Pydantic OrderCreate определяет схему валидации входящих данных.

Поле order_number должно быть уникальным и содержать не более 50 символов.

Поле amount должно быть положительным числом.

from pydantic import BaseModel, Field

class OrderCreate(BaseModel):
order_number: str = Field(..., min_length=1, max_length=50)
amount: float = Field(..., gt=0)

Разбор:

  • Pydantic BaseModel валидирует JSON тела запроса до бизнес-логики: Field(..., gt=0) отклонит нулевую или отрицательную сумму.
  • order_number ограничен длиной 1–50 символов; при ошибке FastAPI вернёт 422 Unprocessable Entity с описанием полей.

См. также Проверка и валидация.

Основной файл main.py содержит роуты для создания заказа и получения списка заказов.

Роут /orders обрабатывает POST-запросы для создания новых записей.

Роут /orders/{order_id} возвращает информацию о конкретном заказе.

Код ITЗагрузка примера кода…

Разбор:

  • FastAPI() создаёт приложение; декораторы @app.post / @app.get регистрируют маршруты и схемы ответа response_model.
  • Base.metadata.create_all(bind=engine) при старте создаёт таблицы в PostgreSQL (в проде обычно миграции Alembic/Flyway).
  • Depends(get_db) внедряет сессию SQLAlchemy на время запроса; BackgroundTasks откладывает публикацию в RabbitMQ, чтобы клиент быстрее получил 201 с id заказа.
  • pika.BlockingConnection и queue_declare(..., durable=True) подключаются к брокеру rabbitmq в Docker-сети; basic_publish с delivery_mode=2 пишет persistent-сообщение в order_events.
  • В create_order проверяется уникальность order_number, затем db.addcommitrefresh сохраняют строку со статусом pending и подставляют сгенерированный id.
  • background_tasks.add_task(send_order_event, ...) ставит событие order.created в очередь после ответа HTTP; Java-сервис подхватит обработку асинхронно.
  • get_order ищет запись по первичному ключу; HTTPException(404) возвращается, если заказа нет в БД.

Запуск сервиса:

uvicorn main:app --reload --host 0.0.0.0 --port 8001

Разбор:

  • uvicorn main:app запускает ASGI-приложение FastAPI: main — модуль, app — объект приложения; --reload перезагружает код при правках.

Документация API доступна по адресу http://localhost:8001/docs.


Сервис обработки заказов на Java

Сервис обработки заказов читает pending-заказы из базы данных, выполняет бизнес-логику проверки и обновления статуса, а затем отправляет событие в очередь RabbitMQ.

Для реализации используется Spring Boot с библиотеками Spring Data JPA для работы с базой данных и Spring AMQP для взаимодействия с RabbitMQ.

Зависимости проекта Maven включают следующие пакеты:

  • spring-boot-starter-web,
  • spring-boot-starter-Data-jpa,
  • postgresql-driver,
  • spring-boot-starter-amqp,
  • lombok,
  • validation.

Файл pom.xml содержит конфигуцию сборки проекта с указанием версий зависимостей и настроек компиляции.

Код ITЗагрузка примера кода…

Разбор:

  • Блок <dependencies> в pom.xml подключает Spring Web, JPA, драйвер PostgreSQL и Spring AMQP — Maven подтянет их при сборке.

Модель Order соответствует структуре таблицы в базе данных.

Используется аннотация @Entity для связи с таблицей, @Id для первичного ключа и другие аннотации для управления отображением полей.

Код ITЗагрузка примера кода…

Разбор:

  • @Entity и @Table связывают класс с таблицей PostgreSQL; @Id + @GeneratedValue дают автоинкрементный первичный ключ.
  • @Enumerated(EnumType.STRING) хранит статус заказа текстом (PENDING, COMPLETED), а не числовым кодом enum.
  • Пакеты model, repository, service разделяют слои — сущность, доступ к данным, бизнес-логика обработки заказов.

Репозиторий OrderRepository расширяет интерфейс JpaRepository и предоставляет методы для поиска заказов по статусу.

Метод findByStatusOrderByCreatedAtAsc возвращает список всех заказов со статусом PENDING, отсортированных по дате создания.

package com.example.orderservice.repository;

import com.example.orderservice.model.Order;
import com.example.orderservice.model.Order.OrderStatus;
import org.springframework.Data.jpa.repository.JpaRepository;
import java.util.List;

public interface OrderRepository extends JpaRepository<Order, Long> {
List<Order> findByStatusOrderByCreatedAtAsc(OrderStatus status);
}

Разбор:

  • Интерфейс JpaRepository<Order, Long> даёт CRUD без SQL; имя метода findByStatusOrderByCreatedAtAsc Spring Data разберёт в запрос автоматически.
  • Пакеты model, repository, service разделяют слои — сущность, доступ к данным, бизнес-логика обработки заказов.

Сервис OrderProcessingService содержит основную бизнес-логику.

Метод processPendingOrders выбирает все pending-заказы, обновляет их статус на PROCESSING, а затем на COMPLETED, имитируя выполнение работы.

После успешной обработки заказ отправляется в очередь RabbitMQ.

Код ITЗагрузка примера кода…

Разбор:

  • Интерфейс JpaRepository<Order, Long> даёт CRUD без SQL; имя метода findByStatusOrderByCreatedAtAsc Spring Data разберёт в запрос автоматически.
  • @Service регистрирует класс в контексте Spring; @Autowired внедряет репозиторий и RabbitTemplate для AMQP.
  • Цикл переводит заказ PENDINGPROCESSINGCOMPLETED; Thread.sleep имитирует долгую работу; при прерывании статус станет FAILED.
  • rabbitTemplate.convertAndSend публикует JSON о завершении в очередь order_events для C#-сервиса уведомлений.

Файл конфигурации application.properties содержит параметры подключения к базе данных, настройку RabbitMQ и порт сервера.

spring.datasource.url=jdbc:postgresql://postgres:5432/orders_db
spring.datasource.username=admin
spring.datasource.password=secret_password
spring.datasource.driver-class-name=org.postgresql.Driver

spring.rabbitmq.host=rabbitmq
spring.rabbitmq.port=5672
spring.rabbitmq.username=admin
spring.rabbitmq.password=secret_password

server.port=8082

Разбор:

  • spring.datasource.* настраивает JDBC к PostgreSQL в Docker-сети; spring.rabbitmq.* — хост, порт и учётка брокера.
  • server.port=8082 выделяет Java-сервису отдельный порт API в polyglot-стенде.

Запуск сервиса:

mvn spring-boot:run

Разбор:

  • mvn spring-boot:run стартует Spring Boot с встроенным Tomcat на порту из application.properties (в демо — 8082).

Сервис автоматически запускает процессор заказов каждые 5 секунд благодаря аннотации @Scheduled.


Сервис уведомлений на C#

Сервис уведомлений слушает очередь RabbitMQ и при получении события о завершении заказа отправляет HTTP-запрос клиенту с информацией о статусе.

Для реализации используется ASP.NET Core Web API и библиотека RabbitMQ.Client.

Установите необходимые пакеты через NuGet:

dotnet add package RabbitMQ.Client
dotnet add package Microsoft.AspNetCore.Mvc.NewtonsoftJson

Разбор:

  • dotnet add package добавляет зависимость в .csproj: RabbitMQ.Client — AMQP, NewtonsoftJson — сериализация тел HTTP.

Модель OrderEvent описывает структуру сообщения, приходящего из очереди. Свойства соответствуют полям JSON-сообщения.

Код ITЗагрузка примера кода…

Разбор:

  • JsonPropertyName сопоставляет поля JSON (orderId) со свойствами C#; десериализатор заполнит объект из тела сообщения RabbitMQ.
  • Пространства имён группируют модели и сервисы; async/await не блокируют поток при HTTP-вызове наружу.

Сервис NotificationConsumer реализует логику подписки на очередь и обработки сообщений.

Метод ConsumeMessages создает подключение к RabbitMQ, объявляет очередь и начинает слушать сообщения.

Код ITЗагрузка примера кода…

Разбор:

  • JsonPropertyName сопоставляет поля JSON (orderId) со свойствами C#; десериализатор заполнит объект из тела сообщения RabbitMQ.
  • IHostedService стартует фоновый consumer при запуске приложения; ConnectionFactory задаёт хост rabbitmq и учётные данные AMQP.
  • QueueDeclare(..., durable: true) создаёт устойчивую очередь; autoAck: false означает, что BasicAck отправляют только после успешной обработки.
  • Обработчик Received читает тело, десериализует OrderEvent и вызывает SendNotificationAsync — HTTP POST на callback с логированием результата.

Файл Program.cs регистрирует сервис в DI-контейнере и настраивает маршруты.

using NotificationService.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddHttpClient();
builder.Services.AddHostedService<NotificationConsumer>();

var app = builder.Build();

app.MapControllers();

app.Run();

Разбор:

  • IHostedService стартует фоновый consumer при запуске приложения; ConnectionFactory задаёт хост rabbitmq и учётные данные AMQP.
  • QueueDeclare(..., durable: true) создаёт устойчивую очередь; autoAck: false означает, что BasicAck отправляют только после успешной обработки.
  • Обработчик Received читает тело, десериализует OrderEvent и вызывает SendNotificationAsync — HTTP POST на callback с логированием результата.
  • AddHostedService<NotificationConsumer>() регистрирует слушателя очереди в DI; MapControllers() подключает REST-эндпоинты.

Дополнительный контроллер NotificationController может принимать прямые уведомления от других сервисов через REST API.

Код ITЗагрузка примера кода…

Разбор:

  • JsonPropertyName сопоставляет поля JSON (orderId) со свойствами C#; десериализатор заполнит объект из тела сообщения RabbitMQ.
  • [ApiController] и [Route] задают префикс URL; [FromBody] биндит JSON тела в OrderEvent для прямых уведомлений.
  • Пространства имён группируют модели и сервисы; async/await не блокируют поток при HTTP-вызове наружу.

Запуск сервиса (из каталога notifications):

dotnet run

Разбор:

  • dotnet run поднимает Kestrel и фоновый NotificationConsumer, который подписывается на очередь order_events.

Сервис автоматически начинает прослушивание очереди при старте приложения.


Взаимодействие через REST API и RabbitMQ

Система использует два типа взаимодействия для достижения оптимальной производительности и надежности. REST API применяется для синхронных операций, где требуется немедленный ответ от сервера. Это подходит для создания новых заказов и получения информации о статусе конкретного заказа. RabbitMQ используется для асинхронной передачи событий, когда операция не требует мгновенного подтверждения и может выполняться в фоне.

При создании заказа через REST API сервис Python возвращает ID созданной записи сразу после сохранения в базу данных. Параллельно в фоне отправляется сообщение в очередь RabbitMQ о том, что заказ создан. Сервис Java на Java считывает этот порядок из базы данных, обрабатывает его и отправляет событие о завершении в ту же очередь. Сервис C# получает это событие и выполняет действие по отправке уведомления.

Такая архитектура обеспечивает развязку компонентов. Если сервис уведомлений временно недоступен, система продолжает работать, так как сообщения сохраняются в очереди до тех пор, пока потребитель не станет доступен. Аналогично, если сервис обработки заказов перегружен, он продолжает читать заказы из базы данных, но скорость обработки ограничивается его собственными ресурсами, не влияя на возможность создания новых заказов.


Runbook — локальный прогон за 10–15 минут

  1. Поднимите инфраструктуру:
docker compose up -d
docker compose ps

Разбор:

  • docker compose up -d поднимает PostgreSQL, RabbitMQ и другие зависимости в фоне; ps показывает, что контейнеры в статусе Up. Шаблоны compose для Postgres и app+db — Docker Compose — готовые стеки.
  1. Убедитесь, что RabbitMQ доступен в браузере по http://localhost:15672 (логин/пароль из docker-compose.yml).
  2. Запустите сервисы в отдельных терминалах:
    • Python: uvicorn main:app --reload --host 0.0.0.0 --port 8001
    • Java: mvn spring-boot:run
    • C#: dotnet run
  3. Создайте тестовый заказ через Swagger (http://localhost:8001/docs) или curl.
  4. Проверьте:
    • запись появилась в PostgreSQL;
    • в RabbitMQ прошли сообщения order.created/completed;
    • в логах notification-сервиса есть отправка уведомления.

Если один шаг падает, фиксируйте проблему на уровне конкретного сервиса и возвращайтесь к цепочке целиком. Такой подход повторяет реальный инцидент-диагноз в продакшене.

Для тестирования системы:

  1. Поднимите инфраструктуру (см. блок docker compose в "Быстром старте" выше).
docker compose up -d

Разбор:

  • docker compose up -d поднимает PostgreSQL, RabbitMQ и другие зависимости в фоне; ps показывает, что контейнеры в статусе Up. Шаблоны compose для Postgres и app+db — Docker Compose — готовые стеки.
  1. В отдельных терминалах запустите сервисы — команды в таблице в начале статьи и в разделах Python, Java и C# (uvicorn, mvn spring-boot:run, dotnet run).
mvn spring-boot:run

Разбор:

  • mvn spring-boot:run стартует Spring Boot с встроенным Tomcat на порту из application.properties (в демо — 8082).
  1. Отправьте POST-запрос на endpoint Python-сервиса для создания заказа.
  2. Проверьте логи сервисов и веб-интерфейс RabbitMQ (http://localhost:15672).

Проблемы, которые стоит решить

  1. Пароли и подключения (admin/secret_password) жестко зашиты в коде. Это рискованно для реальных проектов. Можно использовать переменные окружения или секреты Docker/K8s.
  2. Возможно, стоит оборачивать ключевые моменты в try/catch.
  3. Все сервисы используют одну PostgreSQL. При падении БД упадет вся система. Это анти-паттерн для микросервисов. Каждому сервису — свою БД. Связывать через события, а не через общую таблицу
  4. Сервисы запускаются, но нет проверок их готовности (liveness/readiness probes). В оркестраторе (K8s/Docker) это приведет к отправке трафика в еще не готовый сервис. Желательно добавить /health (liveness) и /ready (readiness) в каждый сервис
  5. Эндпоинт /orders — это v1. При изменении структуры заказа (OrderCreate) вы сломаете всех клиентов. Сразу закладывайте версионирование. Допустим, /api/v2/orders (с новыми полями).
  6. Между сервисами потеряется контекст запроса. Трудно отследить один заказ от создания до уведомления. Добавьте Correlation ID. При создании заказа генерируйте UUID и передавайте его в БД, RabbitMQ, во все логи.
  7. Если отправка уведомления упадет, сообщение потеряется (оно удалено из очереди). Возможно, использовать BasicNack с requeue=true вместо BasicAck до успешной обработки.

Для продакшена к этому списку добавляют централизованные логи, метрики, E2E-тесты в CI и политику секретов (забота о коде и данных).


См. также


Основа по протоколу

Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.


В подборках

Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:

Первые шаги (маршрут подборки) — Первые шаги с Memcached, Первые шаги с Docker и Kubernetes, Первые шаги с Cassandra, Первые шаги с Redis, Первые шаги с MongoDB, Первые шаги с SQL.