← Назад к вопросам

Приведи пример бага из-за которого нельзя сделать релиз

1.3 Junior🔥 301 комментариев
#Работа с дефектами

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Пример критического бага, блокирующего релиз

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

Контекст и воспроизведение

В проекте использовалась распределённая система: сервис A (пользователи) и сервис B (транзакции). Сервис B получал данные через асинхронную очередь (RabbitMQ) и кэшировал их в своей локальной базе. Для повышения производительности, в сервисе A провели миграцию: расширили таблицу users, добавив поле currency (VARCHAR(3)). Обновили код сервиса A и отправили его на тестирование. На тестовых стендах (которые использовали синхронные вызовы между сервисами) всё работало корректно. Однако в продакшене сервис B, не обновлённый до новой версии, продолжил получать сообщения от сервиса A через очередь, но не мог десериализовать обновлённую структуру сообщения, содержащую новое поле.

// Сообщение ДО миграции (версия v1)
{
  "user_id": 123,
  "full_name": "Иван Иванов"
}

// Сообщение ПОСЛЕ миграции сервиса A (версия v2)
{
  "user_id": 123,
  "full_name": "Иван Иванов",
  "currency": "USD"  // Новое поле
}

Код сервиса B (на языке Python с использованием Pydantic) ожидал только поля user_id и full_name:

from pydantic import BaseModel

class UserMessage_v1(BaseModel):
    user_id: int
    full_name: str
    # Поля 'currency' нет

def process_message(raw_data: dict):
    try:
        message = UserMessage_v1(**raw_data)  # Ошибка валидации при получении v2
        save_to_cache(message)
    except ValidationError as e:
        logger.error(f"Invalid message format: {e}")
        # Сообщение уходит в Dead Letter Queue, обработка прерывается

Почему это блокирует релиз

  • Нарушение критической бизнес-логики: Транзакции пользователей перестали обрабатываться, что привело к финансовым потерям и жалобам клиентов.
  • Каскадный эффект: Ошибка в одном сервисе вызвала остановку работы зависимой системы.
  • Сложность и риск hotfix: Потребовалось бы:
    *   Экстренный откат сервиса A к предыдущей версии (но сообщения новой структуры уже могли находиться в очередях).
    *   Или срочное развертывание обновлённого сервиса B (что эквивалентно незапланированному релизу всей системы).
    *   Очистка очередей и восстановление данных, что могло занять часы.
  • Нарушение SLA: Система стала недоступна для ключевой функции, что неприемлемо для клиентов.

Корневые причины и выводы для процесса

Этот баг возник не только из-за ошибки в коде, но и из-за фундаментальных пробелов в процессе:

  1. Отсутствие контрактов (схем) данных между сервисами и контроля их версионирования (например, через Apache Avro или Protobuf).
  2. Неполное тестирование интеграции: На стендах использовалась прямая синхронная интеграция (HTTP), в то время как продакшен задействовал асинхронные очереди. Среды тестирования не соответствовали продакшену.
  3. Нарушение принципа обратной и прямой совместимости (Backward/Forward Compatibility): Новые версии сервиса-отправителя должны были быть совместимы со старыми версиями сервиса-получателя. Следовало реализовать "мягкий" деплой:
    *   Сначала добавить в сервис B обработку нового поля как необязательного (forward compatible).
    *   Затем выпустить сервис B в продакшен.
    *   И только потом выпускать сервис A, который начинает это поле отправлять.

Такой баг делает релиз невозможным, так как его появление в продакшене приводит к немедленной деградации сервиса, требует остановки бизнес-процессов и сложных аварийных работ. Он ярко демонстрирует важность интеграционного и контрактного тестирования, а также соблюдения принципов совместимости API в распределённых системах.

Приведи пример бага из-за которого нельзя сделать релиз | PrepBro