Очереди, потоки, события
Порядок сообщений: построй consumer, переживающий порядок
Читать про опасности порядка — не то же, что видеть, как debit приземляется раньше своего credit, и доказать, что твой дизайн это поглощает. Построй маленький конвейер событий, инъецируй беспорядок, который прод тебе бросит — конкуренцию, retry продюсера, redelivery, DLQ replay — и покажи, что consumer остаётся корректным, с доказательствами на каждом шаге.
Преврати ментальную модель юнита в воспроизводимый инженерный цикл: выбери правильный partition key, укрепи продюсер, сделай consumer идемпотентным и version-guard’нутым, потом намеренно сломай порядок и докажи, что финальное состояние всё равно корректно.
Построй consumer баланса аккаунта (или обновлений профиля) поверх Kafka или SQS FIFO, который обрабатывает per-entity события конкурентно и доказуемо сходится к корректному финальному состоянию даже при переупорядочивании, дублирующей доставке и DLQ replay — с тестовым харнессом, это демонстрирующим.
- Лог прогона, показывающий конкурентных consumer'ов, обрабатывающих несколько сущностей параллельно, при этом события одной сущности держатся в порядке версий несмотря на приход не по порядку.
- Свидетельство срабатывания version guard: счётчики применённых против пропущенных (устаревшие/дубликаты) событий и финальное per-entity состояние, совпадающее с ожидаемым in-order состоянием.
- Тест с форсированным retry или дублирующей доставкой, который переупорядочил бы или применил дважды на наивном consumer'е, но оставляет твоё финальное состояние корректным.
- Короткий разбор, называющий выбранный partition key и почему, плюс какой механизм (партиционирование, idempotence, version guard) поймал каждый класс беспорядка.
- Запусти репартиционирование (вырасти partition Kafka или смени ключевание) и покажи переходную порчу порядка, потом покажи, что твой version-guard'нутый consumer всё равно сходится к корректному состоянию.
- Добавь on-call runbook: как заметить переупорядочивание по ключу в метриках, чеклист конфига продюсера/consumer'а и безопасная процедура DLQ replay (rate-limited, version-guarded).
- Замени version guard коммутативными / last-write-wins эффектами (set balance = X вместо add X) и сравни, какой класс операций терпит каждый дизайн.
- Прогони ту же нагрузку на другом брокере (Kafka, если начал с SQS FIFO, или наоборот) и сравни, как каждый выражает per-key порядок и в какой потолок пропускной способности упирается один ключ.
Это цикл, который ты запустишь на каждом реальном дизайне порядка: выбери partition key как границу консистентности, укрепи продюсер, чтобы он не мог переупорядочить у источника, сделай consumer идемпотентным и version-guard’нутым, чтобы redelivery и DLQ replay были no-op, потом намеренно инъецируй беспорядок и докажи, что финальное состояние всё равно сходится. Сделав это один раз на игрушечном конвейере — и увидев, как version guard отвергает устаревший debit — превращаешь production-версию в мышечную память.