Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Асинхронная коммуникация в Go: от понятного к д...

Асинхронная коммуникация в Go: от понятного к душному. Дима Некрасов, Otello, 2ГИС

Этот доклад — не про rocket science и не про «всё и сразу». Здесь 20% практики, которой хватит, чтобы закрыть 80% задач. Остальное — духота, но иногда без неё нельзя: когда масштаб, нагрузка, или просто пора уже делать «как надо».

Простой мир синхронных вызовов рано или поздно заканчивается. Сначала появляется очередь. Потом — очередь для очереди. Потом — типы сообщений, форматы, порядок, idempotency, и вся эта «архитектура». Сначала ты просто пишешь сервис. Потом ты отвечаешь за то, чтобы сообщения не терялись.

Ты можешь не запоминать всё. Но что-то точно пригодится. А если не сейчас — то через два созвона и один инцидент.

Avatar for Lamoda Tech

Lamoda Tech

May 06, 2025
Tweet

More Decks by Lamoda Tech

Other Decks in Technology

Transcript

  1. Кто я? • Больше 10 лет в ИТ; • Работал

    в отечественных и иностранных компаниях; • Тех лид, архитектор, программист; филантроп, миллиардер; • Фокус на: • маленькие команды и большие проекты; • какие эвристики позволяют затаскивать проекты быстро. • На 146% уверен, что архитектура ускоряет разработку и позволяет делать в срок.
  2. Disclaimer • Будут эвристики, которые помогают быстро принять решение. •

    В проектировании в первую очередь полагаюсь на две метрики: • Связность системы (coupling) - на сколько взаимозависимы модули • КТО выполнит работу • КОГДА выполнит работу • Влияние на бизнес • Core / non-core domain • Влияние при падении • Здесь точно не будет всего, только основное.
  3. Disclaimer • Эвристика – это упрощенные практические правила, благодаря которым

    делать что-то становится проще и легче. — Насим Талеб.
  4. Disclaimer • Эвристика – это упрощенные практические правила, благодаря которым

    делать что-то становится проще 
 и легче. 
 — Насим Талеб. 
 • Главное преимущество таких правил в том, 
 что применяющий их знает: они далеки 
 от совершенства и всего лишь полезны.
 Опять — Насим Талеб.
  5. О чем пойдет речь • Зачем мне это надо ?

    • Теоретическая часть • Виды асинхронной коммуникации • Порядок • Типы сообщений • Тип полезной нагрузки в сообщение • Тип полезной нагрузки по полезности • Немного про размер • Повседневные эвристики
  6. Зачем мне это надо? Синхронность — совпадение и связь по

    времени чего-либо совершающегося (википедия) • Можно все построить на синхронных вызовах, RPC и тд • Делайте так в базовом случае • Точно знаем когда будет выполнено • Блокируемся ожидая ответа • Результат нужен здесь и сейчас Асинхронность — не совпадающий с чем-либо во времени (википедия) • Антоним синхронности • Мы не знаем когда выполнится • У нас может быть только обещание, что работа будет выполнена • Не блокируемся ожидая ответа • Результат не нужен здесь и сейчас
  7. • Когда выбирать асинхронность: • Когда не нужен мгновенный ответ

    • Сама природа процесса асинхронная • Необходима доступность системы • Необходима масштабируемость системы • Стабильность системы • И тд. Зачем мне это надо?
  8. Сама природа процесса асинхронная • Онлайн платежи • На платеж

    выделяется 20 минут, 
 нет смысла блокироваться.
  9. Виды асинхронной коммуникации Плюсы: • можно брать данные не сразу

    • можно работать батчами • можно делать перепроцессинг Минусы: • если нагрузка не высокая то будет крутиться в холостую • сложнее масштабироваться под пиковые нагрузки Pull based
  10. Виды асинхронной коммуникации Push based Плюсы: • шина мгновенно шлет

    сообщение в потребителя • легко масштабироваться под пиковые нагрузки Минусы: • нет лога сообщений • может натолкать много событий в потребителя
  11. Гибридный через back-pressure • Включает в себя плюсы подходов •

    Редкий зверь Виды асинхронной коммуникации
  12. Почему редко влияют? Виды асинхронной коммуникации • Используйте то, что

    принято у вас в компании • Должна быть серьезная причина
 использовать что-то другое
  13. Порядок (ordering) • Проблемы с порядком событий будут встречаться
 практически

    во всех подходах • О них надо знать и понимать откуда они происходят
  14. • Необходимо учитывать бизнес • Сложно дать общую рекомендацию •

    Использовать векторные часы, которые укажут на порядок и причинность : 
 Created { Version : 1 }
 Booked { Version : 2 } • можно использовать механизм версионирования из RDBMS • Смотреть технологии, которые используются у вас в компании и что предлагают для решения проблем. • Завязываетесь на конкретную технологию Порядок (ordering)
  15. Виды сообщений • Мы командуем кому-то выполнить задачу, 
 повелительное

    наклонение • Это оркестрация — клиент определяет место
 потребителя в бизнесс процессе • Связность - знаем КТО будет выполнять работу • N клиентов -> 1 обработчик • Ок, когда в пределах одного домена: 
 команда изменить размер картинки Команды (commands):
  16. События (events) • хореография - потребитель сам определяет 
 свое

    место в бизнесс процессе • нет связности - не знаем КТО и КОГДА • отчет о том что произошло 
 в системе - payment_paid, 
 booking_booked • можно использовать 
 вместо команд • 1 событие ->
 N потребителей Виды сообщений
  17. Как трансформировать событие 
 в команду • На стороне публикатора

    ( open-host ) • Публикатор знает про потребителя
  18. Как трансформировать событие 
 в команду • На стороне потребителя

    (anti-corruption layer ) • Потребитель знает про публикатора
  19. Как трансформировать 
 событие в команду • Не у публикатора

    
 и не у потребителя • У вас есть менеджер процессов. • В вашей системе его может 
 и не быть.
  20. Виды сообщений Я бы еще выделил уведомления (notifications): • считаю,

    что это анти-паттерн • полезно знать • использовать осторожно • связность сильная
  21. Проблемы нотификации (notifications) Проблемы: • Cвязность сильная • Потребители порождают

    M (кол-во событий) x N (кол-во потребителей) нагрузку • Когда потребитель придет за данными он может получить новые данные
  22. Полезные уведомления (notifications) Иногда могут быть полезны: • Строгие требования

    к длине сообщения - смс, твиттер • Смс от МЧС с предупреждением и ссылкой на прогноз • Переправить большие данные
  23. Разница (delta, diff, action) Плюсы: • События будут меньше по

    размеру • Если изменения частые – можно выиграть в трафике Минусы: • Исправление проблем со схемой событий ( например: gdpr ) • Придется сильнее думать об event ordering • Может понадобиться полный агрегат • Сложно выработать формат передачи Виды полезной нагрузки в сообщении
  24. Состояние (state, fact) Плюсы: • Легко имплементировать • Получаем текущий

    слепок состояния • Если меняется схема событий – проще исправить одно state событие, чем много delta; Минусы: • Cобытие может оказаться слишком большим • Не понятно что изменилось, если ордеринг событий нарушится • Если изменения частые, может быть действительно слишком много лишних данных об одном и том же Виды полезной нагрузки в сообщении
  25. Состояние (state, fact) Пример: ImageResized { "ImageId" : 123, "Sizes"

    : [ "500x500", "640x480", ], "PathToFile": "resizedImages/123" }
  26. Виды полезной нагрузки в сообщении • Гибрид • Шлют состояние

    
 и то, что изменилось ImageResized { "State": { "ImageId": 123, "Sizes": ["500x500", "640x480"], "PathToFile": "resizedImages/123" }, "Action": { "NewSize": "500x500" } }
  27. Полезность / полнота полезной нагрузки ( Event granularity ) •

    Coarse ( обобщенный ) • Fine ( конкретный, гранулярный )
  28. Полезность / полнота полезной нагрузки ( Event granularity ) Coarse

    ( обобщенный ) • События большие и общие, имею обобщенное имя и много данных не обязательных; • Необходимо проверять, что же все-таки случилось и принимать решение реагировать или нет; • Обобщенность позволяет легче развивать домен. PaymentChanged { "Status" : "Paid", "PaymentId" : 123, "TotalAmount" : 12345, "CustomerEmail" : "[email protected]", "CustomerPhone" : «8999123123123", "Transactions" : [ { "OpperationType" : "Charge", "Status" : "Success" } ] }
  29. Полезность / полнота полезной нагрузки ( Event granularity ) Fine

    ( конкретный, гранулярный) • Такие события слишком мелкие и специфичные; • Чаще нормально называются; • Но тяжело обеспечивать поддержку событий которых может быть слишком много; • Может не хватать данных для реакции PaymentPaid { "PaymentId" : 123, "TotalAmount" : 12345 }
  30. Fine ( конкретный, гранулярный ) Гранулярных событий может быть слишком

    много: BookingCreated {} BookingPending {} BookingWaitingForProvider {} BookingSentToProvider {} BookingBooked {} BookingPenaltyAdded {} BookingPenaltyApplied {} BookingCheckedOut {} BookingComplete {} …
  31. Полезность / полнота полезной нагрузки 
 (Event granularity) • В

    2GIS распространен стриминговый подход • Используют Coarse + State
  32. Размер сообщения • В идеале — меняй архитектуру • Не

    получается архитектуру — меняй форматы: ✓Avro, MessagePack и тд. • В ход может пойти даже компрессия.
  33. 20%

  34. Тип сообщения • Событие (еvent, domain event) • Почему?: •

    Низкая связность • Легко имплементировать • Подходит под много сценариев • Может заменить собой команду 
 (через anti-corruption layer)
  35. Тип полезной нагрузки в сообщение • Состояние (state, fact, модель

    целиком) • Почему: • Легко имплементировать; • Подходит многим; • Не надо аккумулировать агрегат.
  36. • Coarse (грубая, обобщенная): • С нюансами • Выделить три

    вида событий: создание, изменение, завершение • Почему: • легко имплементировать; • меньше думать над порядком; • закрывает много сценариев. Тип полезной нагрузки по полезности (event granularity)