Это продолжение цикла статей про разработку архитектуры. Ссылки на статьи:
Event driven architecture (EDA)
Ещё одна из популярных архитектур — Event driven architecture (EDA), что в переводе на русский означает “архитектура на основе событий”. Суть данной архитектуры состоит в том, что приложение работает с событиями (эвентами), которые генерируются пользователем или другими системами.
Предположим, у нас есть метод для обновления локации пользователей в нашей базе данных. В таком случае стандартный запрос будет выглядеть следующим образом:
Юзер послал запрос на сервер, который в свою очередь сходил в базу данных и обновил в ней данные. И всё бы хорошо, но если у нас процесс обновления локации будет содержать сложные проверки и вычисления, то это негативно повлияет на общую скорость работы системы и, как следствие, на user experience. В таком случае наши пользователи просто начнут отваливаться и не обновят запросы в базе данных. Если у нас процесс занимает какое-либо время, то лучше это спроектировать, используя паттерн эвентной архитектуры. В таком случае на запрос пользователя будет создан только эвент, говорящий о том, что пользователь хочет обновить определенные данные в базе. Однако все проверки и само обновление будет выполняться уже позже и другим сервисом. На схеме это будет выглядеть так:
Юзер сделал запрос на сервер и создал эвент о том, что хочет обновить данные в базе. Этот эвент кладется либо в очередь сообщений, либо в Kafka, это уже дело вкуса.
После этого отдельный сервис видит, что у нас появился новый эвент, и начинает его выполнять все необходимые проверки, после чего обновляет данные в базе данных и в этот момент эвент считается выполненным.
То есть, если вы хотите, чтобы ваши микросервисы общались в архитектуре EDA, то выглядеть у вас это будет примерно так:
На самом деле, данная архитектура несёт в себе много недостатков, хотя есть и преимущества. Давайте, по классике, начнём с недостатков:
Появляется новая шина сообщений, которую тоже нужно поддерживать, чтобы она была стабильной, а также масштабировать вместе с проектом и бэкапить или шардировать данные.
Появляется дополнительная задержка и отложенная синхронизация. Это может привести к тому, что запрос может выполняться дольше требований и пользователь не сразу видит свои изменения.
Требуется больше вычислительных ресурсов на создание эвентов и их чтение. При неоптимальном подходе эвентная архитектура может занимать до 50% вашего процессорного времени сервера, хотя конечно, как правило, если такую архитектуру использовать правильно и в нужном месте, то использование накладных ресурсов не будет превышать 10-15% мощности сервера.
Также появляется единая точка отказа — это наша шина. К счастью, сейчас шины надёжные, но об этом всё равно нужно помнить.
Требуется много памяти для хранения самих эвентов.
Окей, с недостатками разобрались. Что там по преимуществам?
Мы сохраняем все данные о том, что делал пользователь. В двадцать первом веке данные крайне важны, и при сохранении небольших эвентов мы имеем много информации о пользователе, которую потом можно использовать для машинного обучения.
При правильной настройке шины вы сможете восстановить все действия пользователя досконально. Это очень удобно при тестировании и отлавливании багов, ведь теперь вы всегда чётко знаете, когда и что пользователь делал в системе.
Вы также можете отследить любой момент времени и откатить продукт к состоянию на любую дату.
Становится намного проще распределять нагрузку на сервер по времени суток. Если в системе есть пиковые часы нагрузок, а в остальное время сервер простаивает, то в пиковые часы вы можете просто создавать эвенты, а сервер, предназначенный для их обработки, будет просто постепенно их обрабатывать, не сильно думая о том, что ему это нужно сделать за 10 секунд пока http request пользователя не закрылся.
Наконец, довольно удобно масштабировать сами сервисы, которые занимаются обработкой эвентов: при правильном и достаточно общем подходе у вас может быть написан отдельный сервис, который будет можно просто продублировать.
Как мы видим, эвентная архитектура, или архитектура на основе событий, имеет свои преимущества и недостатки, но в нужный момент она может очень сильно облегчить жизнь проекта и упростить его понимание и написание.
Я так же оставлю ссылку на статью об антипатернах в эвентной архитектуре: "Антипаттерны событийно-ориентированной архитектуры".
Со статьёй помогала @Ethera, за что ей большое спасибо и плюсик в карму, если кто может.)
Комментарии (9)
comerc
19.04.2022 15:01+1Человек старается, хотя уже две первые части заминусовали. Настойчивость - самое главное качество. Плюс в карму и на заметку.
nibb13
19.04.2022 18:22+2Присоединяюсь ко мнению! Материалы интересные, понятные и в перспективе получится полезный гайд для начинающих. Отдельный плюс автору за краткость.
makar_crypt
19.04.2022 19:01И как в этом архитектурном варианте решается проблема "случайно не перезаписать" по американски это называется false positive конкуренция?
Пример всё как у вас: есть сервис БИЛИНГ и ЛОТ:
СРАЗУ УЧТЕМ ЧТО СЕРВИСЫ ВЫПОЛНЯЮТСЯ в 1м экземпляре, в 1 потоке.
1) 2е пользователей одновременно жмут кнопку "купить лот",
2) WEB API создает 2 сообщений в шину для сервиса ЛОТ
3) сервис ЛОТ делает базовые проверки, что лот существует , у него есть цена, и т.д. выплевывает 2 сообщений в шину для БИЛИНГА "списать 500$"
4) БИЛИНГ начинает очухивается и начинает обрабатывать и у 1го и у 2го пользователя удачно списываются деньги. Выплевываеет 2 сообщения обратно в сервис ЛОТ
5) И тут приходит 1е сообщение , мы перезаписываем допустим OWNER_ID=1 у лота, а потом приходит 2е сообщение и бац мы перезаписывает на OWNER_ID=2.
Сразу откину решение что на шаге "3" помечать что этот лот уже в процессе обработки , и 2е сообщение уже на этом этапе откидывать, сказав "брат всё, этот лот уже в процессе сорри". Т.К. когда сообщение 1го человека дойдет до БИЛИНГА, тупа у человека не хватит денег, а мы ВТОРОГО уже откинули, хотя он мог купить т.к. у него хватало денег. Вы хотите терять деньги? я нет.
Надеюсь понятно описал простую ситуацию.
stone_evil
20.04.2022 06:58Все слишком поверхностно, в каждом пункте плюсов\минусов крайне спорные утверждения, а от словосочетания "эвентная архитектура" испытываешь мини-оргазм. Боюсь, что эту статью я бы не рекомендовал "чайникам", только хуже себе сделают.
makar_crypt
20.04.2022 13:28ну если автор не может ответить , а вы профи, могли бы и мне выше ответить
Emil983
20.04.2022 19:00Что-то тут разные вещи смешаны, message bus да и вообще EDA подразумевает именно общение сервисов через события. Вот это "Вы также можете отследить любой момент времени и откатить продукт к состоянию на любую дату" совсем не обязательно подразумевается в EDA. Для этого всё-таки должен быть реализован event sourcing, обычно событие удаляется из шины после того как потребитель его обработал и передал acknowledgement о нем.
lair
Как у вас из Event System Architecture получилось EDA?
Kecven Автор
eda (event driven architecture). Да, ошибочка. Поправлю.