Перейти к содержимому
PET_01 / Командный проект

Сервис доставки еды
Гонка событиймай 2026

Моя рольUser Service, фронтенд на Nuxt, деплой в Kubernetes, исправление потребителей событий в Delivery Service
СрокиМай 2026, учебный триместр
Результат4 микросервиса, 34 gRPC-эндпоинта, кластер в DigitalOcean
crisis_alertЗадача

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

Order Service публикует order.created и order.paid в NATS JetStream, а Delivery Service создаёт доставку по первому и назначает курьера по второму. Когда сервис запустили в двух подах, order.paid иногда обрабатывался раньше order.created. Обработчик не находил доставку, помечал сообщение как ошибочное и отбрасывал его навсегда. Заказ оставался оплаченным, но курьер его не получал.

34
gRPC-эндпоинта
8
методов в User Service
2–6
подов API Gateway (HPA)
Стек[SYSTEM_ARCHITECTURE]

Go-микросервисы и инфраструктура как код

Сервисы общаются по gRPC, асинхронные события идут через NATS JetStream. Каждый сервис по Clean Architecture со своей PostgreSQL. Кластер DOKS из двух узлов поднимается через Terraform, для нагрузочного теста есть сценарий на Locust.

  • Go
  • gRPC
  • NATS JetStream
  • PostgreSQL
  • Redis
  • Nuxt
  • Kubernetes
  • Terraform
codedelivery-service/internal/nats/client.go
// Term = don't redeliver; Nak = retry.
// ErrNotFound is retried: order.paid can arrive
// before order.created is processed.
if errors.Is(err, usecase.ErrInvalidDelivery) {
    _ = msg.Term()
} else {
    _ = msg.Nak()
}
commit 02acc4f
Решения

5 коммитов

Что бы сделал иначе

Порядок событий нельзя считать гарантированным, как только потребителей больше одного. Гонку я нашёл, только когда сервис запустили в двух подах. Сейчас я бы с самого начала сделал обработчики идемпотентными и описал состояния заказа явно.