Разработать архитектуру системы уведомлений

Мне нужно разработать систему уведомлений, которая будет отправлять уведомления пользователям, когда происходят события.

У меня есть микросистемная среда, на самом деле, когда происходит событие, ms отправляет сообщение в очередь (q.send-event), которое будет использоваться микрослужбой уведомлений. Слушатель очереди q.send-event фактически делает REST-вызов микросервису пользователей, чтобы собрать список всех пользователей, которые получат уведомление. После того, как список пользователей собран, он сохраняет уведомления в базе данных.

Я чувствую, что этот подход не так масштабируем, можете ли вы предложить мне более эффективный подход? Спасибо

если то, что вы чувствуете не масштабируемым с этим подходом, имеет место (большое количество пользователей, собранных из службы пользователей), вы можете сказать службе пользователей, чтобы они помещались в вашу очередь (например, Rabbitmq), чем служба sms потребляет их из очереди, поэтому пользовательский сервис будет обрабатывать разбиение на страницы, и вы можете избежать передачи огромного количества данных через http body

islemdev 07.01.2023 15:51

То, что вы просите, - это мнение и рекомендации, которые не относятся к теме SO. На какие темы здесь можно задать вопросы?

Rob 07.01.2023 15:52

Наверное, лучше спросить об этом на Software Engineering (см. softwareengineering.stackexchange.com/help/on-topic)

Roman 07.01.2023 16:22

О каком масштабе вообще идет речь?

Peter Csala 10.01.2023 12:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
4
240
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Очень масштабируемое решение (см. диаграмму арки) похоже на то, что вы описываете, но если бы я собирал его, я бы использовал Kafka или управляемую Kafka с подключением данных к вашей базе данных (например, разъем Debezium для MySQL). Этот коннектор будет выполнять сбор измененных данных (CDC) и передавать эти события с помощью очередей Kafka.

Причина, по которой здесь важно использовать Kafka по сравнению с AWS MQ или каким-либо другим решением для очередей, таким как RabbitMQ, заключается в том, что Apache Kafka гарантирует доставку событий в правильном порядке, даже если у вас есть несколько потребителей. И Rabbit, и управляемый MQ могут давать аналогичные гарантии, но это не работает, когда вы вводите много потребителей потока событий.

Что касается компонента обмена сообщениями вашего решения, было бы более прагматично и масштабируемо публиковать сообщения в службу веб-перехватчиков или аналогичную, которая является потребителем ваших очередей kafka и записывает события в отдельную базу данных, чтобы можно было подписаться на поток событий. вместо того, чтобы полагаться на сервис, который должен знать, кто его потребители.

Итак, ваша интуиция верна, что это решение не является невероятно масштабируемым, хотя и не является «плохим» решением в любом случае. Две рекомендации, которые я дал, я думаю, помогут вам продвинуться вперед в масштабируемости.

Надеюсь, это помогло. Ваше здоровье.

Ответ принят как подходящий

Прослушиватель очереди q.send-event фактически делает REST-вызов микросервису пользователей, чтобы собрать список всех пользователей, которые получат уведомление.

В микросервисной архитектуре синхронные вызовы между сервисами в общем случае считаются не лучшим вариантом. В этом случае я думаю, что стандартный подход с дублированием данных - это путь:

notifications поддерживает доступную только для чтения копию user данных (только релевантную), которая асинхронно обновляется через брокера сообщений (т. е. каждое обновление данных в службе user создает соответствующее сообщение, которое используется подписчиками, одним из которых является notifications, которое собственное хранилище). Это устраняет необходимость вызова users во время обработки q.send-event.

В дополнение к этому вы можете полностью перенести настройки уведомлений пользователей в службу notifications (лучше сделать это, переместив настройки уведомлений в отдельную часть пользовательского интерфейса или управляя этим с помощью шлюза BFF/API). Я бы сказал, что с точки зрения бизнес-логики/предметной области notification сервис может быть естественным владельцем настроек уведомлений пользователя (если вы не хотите ввести другой сервис):

Обратите внимание, что реальная «наилучшая» реализация может сильно зависеть от реальных бизнес-требований, объемов данных и соглашений об уровне обслуживания.

Вы можете использовать что-то вроде socket.io для трансляции уведомлений всем/некоторым пользователям в режиме реального времени. Вам придется настроить его как на стороне сервера, так и на стороне клиента, если вы хотите начать быстро, есть управляемые решения, такие как Pusher, которые вы можете использовать.

Существует множество подходов, когда вы хотите создать масштабируемое решение системы уведомлений. Это был мой подход, когда я построил подобную систему. Основные компоненты моей системы:

  1. Служба пользователей: здесь вы управляете своей информацией о пользователе и предоставляете API для получения сведений о пользователе.

  2. Служба доставки: в зависимости от различных каналов доставки, которые вы хотите использовать, например, SMS или электронную почту для доставки сообщений. Вы создадите компонент, который будет отвечать за доставку уведомлений вашим пользователям.

  3. Служба событий: создайте прослушиватель, который получает события от других служб и инициирует соответствующие уведомления.

  4. База данных и очередь сообщений: я использовал Kafka (очередь сообщений) с подключением данных к моей базе данных (MySQL — в ней хранится информация об уведомлениях и пользователях). Kafka отделяет службу событий от службы уведомлений и обрабатывает большое количество событий.

  5. Шлюз API: создайте компонент, который выполняет REST-вызов микрослужбы пользователей, чтобы собрать список всех пользователей, которые получат уведомление. Это служит точкой входа для внешних клиентов для доступа к API системы уведомлений.

  6. Мониторинг и ведение журналов. Наконец, вы можете использовать сервисы AWS для мониторинга вашей системы и устранения неполадок, такие инструменты, как Elasticsearch, Logstash и Kibana (ELK), можно использовать для сбора и анализа данных журналов.

Если вы все еще в замешательстве и вам нужна наглядная схема, я могу проверить свою архитектурную схему и загрузить ее.

Насколько я понял, вам нужен только список идентификаторов пользователей для отправки уведомлений. Здесь вы можете использовать метод подписчика издателя. Микросервис User предоставит информацию о пользователе всем своим подписчикам.
Для этого есть несколько способов, я упомяну здесь несколько методов:

  1. Пользовательская служба может отправлять пользовательские события в очередь сообщений для ex-Kafka, а служба уведомлений может подписаться на эту очередь и получать информацию о пользователе.
  2. Пользовательская служба может предоставить API для регистрации различных служб в качестве подписчика и пользовательских событий (вы можете выбрать, для каких пользовательских событий) он будет уведомлять своего подписчика о том, что эти идентификаторы пользователей были обновлены или добавлены.

Имея этот механизм, служба уведомлений будет хранить информацию об идентификаторе пользователя и может использовать ее для асинхронной отправки уведомлений пользователям. Поскольку точный вариант использования здесь не ясен, вы можете использовать эти методы и изменять их в соответствии с вашими потребностями, и если это решение вам не подходит, добавьте дополнительную информацию о своем варианте использования.

Другие вопросы по теме

Где реализовать алгоритм экспоненциального отката в системе контроллер-рабочий?
Маршрутизация трафика на основе HTTP-заголовков
Обрабатывать одновременный доступ в нескольких очередях заданий с несколькими работниками
ATF Dropbox — как функции/обратные вызовы хранятся в базе данных?
Разработка поиска в Твиттере — как сортировать большие наборы данных?
Почему аварийное восстановление намного проще для базы данных только для добавления?
Дизайн системы: как мне разработать RESTful API, который позволяет асинхронно запрашивать результаты
Как может транзакция (Hyperledger Sawtooth) существовать в нескольких блоках одновременно?
Обеспечьте реализацию чистой виртуальной функции, возможно, с другим типом аргумента
Как узел Hyperledger Sawtooth Validator может иметь «количество одноранговых узлов, превышающее максимальное количество подключений» в сети Sawtooth?