Микросервисная архитектура для собеседования: Transactional outbox | Эйч Навыки
Vložit
- čas přidán 16. 07. 2023
- В этом видео наш ментор и лектор Саша Сахаров разбирает один из паттернов микросервисной архитектуры: Transactional outbox.
Наш бот, с помощью которого можно апнуть грейд и зарплату или устроиться в компанию мечты: t.me/skills_mentee_bot?start=....
Сервис развития карьеры Эйч: h.careers/
Репозиторий с кодом: github.com/ansakharov/golang-...
Чат Навыков в телеграмме: t.me/naviky_chat
Группа Саши в телеграмме: t.me/SashaThug - Zábava
Спасибо, ждем всю серию по паттернам микросервисной архитектуры :D
Вот такой формат разбора паттернов просто великолепен!
давно не было видео, спасибо!
о, вы вернулись, ура!
Огонь🎉
спасибо!
контент огонь!
Ждёмс !)))
прикольно, спасибо. Встречал чуть более сложную, но более универсальную реализацию для разных заданий. Смысл, что у нас есть outbox сервис, который вычитывает джобы из таблицы, а джобы могут быть разные, но с одним интерфейсом. Мы их создаем уже с конкретными реализациями, что нужно сделать для джобы: пульнуть в кафку или в вебсокет и т.д., а outbox только достает джобы из таблички в режиме for update, мапит джобу по имени из внутреннего (или внешнего) кеша, дает время на выполнение и если нет ошибок - удаляет из таблицы. Не знаю, зачем я это написал, но может кому пригодится)
Огонь
❤
Пара ошибок в финальном коде:
1. Нельзя ходить по сети (писать в очередь) во время транзакции (постгрес не любит долгих транзакций, возникает блоатинг данных и индексов, забивается пул соединений).
2. Не понятна роль транзакции вообще в продюсере. Ниже написали про FOR UPDATE - он норм. Я бы ещё предложил сделать не true/false, а стейты типа waiting/processing/processed. В таком случае мы будем знать какие события уже обрабатываются, а какие нужно послать второй раз.
Что я имею вам сказать)
- транзакция действительно излишняя, можно обойтись без нее, не держать соединение
- For update не поможет: если откажетесь от транзакции и станете слать парой воркеров данные, то после выполнения select первым, второй подхватит те же данные
- waiting/processing/processed хорошая идея, в видео я показал крупными мазками
Хороший паттерн. Только запись в аутбокс я сделал через хранимую функцию и триггеры где указываю из каких таблиц надо добавить записи в аутбокс, чтоб не зависеть от реализации на клиенте.
Спасибо большое за видео, а какие ещё паттерны микросервисов обычно спрашивают и что из них по хорошему нужно знать, а то их там порядка 60, какие приоритетней?
Если требуется outbox на другие сушности, помимо заказа, то создаем на каждую сущность свою outbox табличку или в одной как-то по типам разделяем ? entityType, entityID или что-то в этом роде
Хотелось бы уточник два момента
1. В воркере не нужна транзакция, если он один. Т.к. мы получаем данные, отправляем в очередь, обновляем таблицу. Если бы воркеров было несколько то можно было бы заюзать транзакцию для Select for update
2. И есть сомнения, что хорошо балково отправить сообщения в кафку, а потом балоково обновоить бд. Может лучше по одной, хотя бы достать какое то количество, а отправлять и помечать что отправлен по одной строчке.
Из воркера можно и убрать транзакцию, правда.
А чем балк смутил? По одной несерьезно отправлять
а в Goland есть снипет что бы не писать каждый раз "if err итд" можно на строке ниже необработанной ошибки прст жмакать ctrl+j и писать err и он сам всё сделает)
В конце Relay сервису не плохо бы организовать подписку на изменения если все горутины вышли чтобы когда платежки редкие задержка была меньше. Вроде про это не сказано.
А как решать конкурентный доступ к одним и тем же данным? Есть воркеры, которые данные из outbox выгребают периодически и если еще и воркера подписать на онлайн изменения, то как защититься от одновременной работы с одной и той же записью? Ведь может так совпасть что онлайн воркер начнет отправлять сообщение, которое поднял уже другой воркер
Один ноль один мой друг. Хочу в backend, выбираю между PHP, Golang, c# и Java, что посоветуешь, чтобы легче было устроиться на работу с перспективой?
Спасибо за видео.
А зачем сохранять в outbox таблицу, мы же можем подписаться на WAL каким-нибудь коннектором (например kafka) ?
А WAL разве не просто поток данных? Просто что будет если транзакция отвалится, у нас ведь данные уже будут в WAL, получается коннектор их уже увидит, но коммита не было. Коммит конечно в WAL тоже появляется, но получается получатель данных из WAL должен уметь чекать транзакции и отбрасывать из потока данных от WAL те, по которым не было коммита
@@wafflebootWAL гарантирует что если транзакция отвалится, то при старте сервера то что было в WAL накатится.
Не очень понятно как поступить когда хочется отправлять сообщение тут же, а не ждать когда воркер проснется и вытащит из outbox запись. Допустим у нас несколько узлов и на каждом узле несколько воркеров. Как сделать так чтобы отправка сообщения шла тут же, не ждать когда их воркер поднимет и при этом защититься от одновременной обработки одного и того же сообщения разными брокерами
А зачем апдейтить когда только true/false, если можно удалить сразу?
На другой стороне могут потерять данные: авария кафки, баги в коде.
Так останется лог по которому можно еще раз отправить события, обновив таблицу sent true -> false для массива "пролитых" сообщений.
Пример: команда аналитики теперь считает новыми алгоритмами, и может отдать пользователю более качественный результат. Но старые данные они уже посчитали и сохранили. Как быть? Переливаем данные сообщения в этот или в другой топик, специально для них, пусть пересчитают и отдают более точную аналитику по событиям трехмесячной давности
10:18 плохо не то, что ОН заливает, а что у ВАС ревью херовое