Как разработать масштабируемую систему уведомлений? [закрыто]

32

Мне нужно написать системный менеджер уведомлений.

Вот мои требования:

Мне нужно иметь возможность отправлять уведомления на разных платформах, которые могут быть совершенно разными (например, мне нужно иметь возможность отправлять SMS или электронную почту).

Иногда уведомление может быть одинаковым для всех получателей для данной платформы, но иногда это может быть уведомление для получателей (или нескольких) для каждой платформы.

Каждое уведомление может содержать информацию о платформе (например, MMS может содержать звук или изображение).

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

Это двухэтапный процесс, сначала клиент может напечатать сообщение и выбрать платформу для отправки, и необходимо создать уведомление (я) для обработки в реальном времени или позже.

Затем система должна отправить уведомление поставщику платформы.


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

У меня есть следующие объекты (на псевдо-языке):

универсальный Notificationобъект:

class Notification {
    String                 $message;
    Payload                $payload;
    Collection<Recipient>  $recipients;
}

Проблема со следующими объектами в том, что если у меня 1.000.000 получателей? Даже если Recipientобъект очень маленький, он займет слишком много памяти.

Я также мог бы создать одно Уведомление для каждого получателя, но некоторые провайдеры платформы требуют, чтобы я отправлял его в пакетном режиме, что означает, что мне нужно определить одно Уведомление с несколькими Получателями.

Каждое созданное уведомление может храниться в постоянном хранилище, таком как БД или Redis.

Было бы хорошо объединить это позже, чтобы убедиться, что оно масштабируемо?

На втором этапе мне нужно обработать это уведомление.

Но как я могу отличить уведомление от правильного поставщика платформы?

Должен ли я использовать объект, как MMSNotificationрасширение abstract Notification? или что-то вроде Notification.setType('MMS')?

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

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

Затем я представляю NotificationProcessorобъект, для которого я мог бы добавить NotificationHandlerкаждый, NotificationHandlerкоторый будет отвечать за подключение провайдера платформы и выполнение уведомлений.

Я также могу использовать, EventManagerчтобы позволить подключаемое поведение.

Есть отзывы или идеи?

Спасибо, что уделили время.

Примечание: я привык работать в PHP и, скорее всего, это мой язык.


Изменить (в соответствии с ответом morphunreal)

  • Сколько сообщений в секунду вы отправляете (Определите текущие / начальные уровни, определите максимальный уровень, который система должна обработать перед перепроектированием)
  • Какие аппаратные ограничения есть у системы (память, процессор и т. Д., Доступные для системы)
  • Как будет масштабироваться оборудование (например, добавление дополнительных серверов, облачные вычисления и т. Д.)

  • Какие языки / системы будут генерировать уведомления?

Я отвечаю за создание уведомлений программно, но на основе пользовательского интерфейса.

  • Знает ли генератор получателей сообщения (?) Или они предоставляются какими-либо другими средствами (т. Е. Бизнес-правила для определенных типов оповещений переходят к определенным получателям)

Должна быть возможность создания уведомления для конкретных получателей, группы получателей (например, с помощью системы тегов) или для всей платформы.

  • Существуют ли бизнес-правила для добавления CC / BCC / Read квитанций

Да. Обратите внимание, что это действительно зависит от платформы, и чтение или CC доступны не на всех платформах.

  • Известен ли генератору тип отправляемого им сообщения (например, SMS / электронная почта) или он основан на получателе

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

  • Требует ли генератор подтверждения отправки / получения / чтения сообщений (асинхронная или синхронная отправка)

Хорошо, система должна быть подвержена ошибкам, но мы хотели бы обработать ошибку, чтобы определить набор правил, например, если сервер недоступен, уведомление должно быть поставлено в очередь для дальнейшего процесса, но если уведомление является неправильным (или было определяется провайдером платформы как есть) он не должен ставиться в очередь, а должен быть уведомлен.

  • Существуют ли требования для хранения истории источников / получателей сообщений (как долго?)

Да, мы, вероятно, хотим сделать некоторую статистику и отчет. * Определить конечные точки уведомления


  • Какие сервисы используются для отправки сообщений? Зависит от того, что некоторые являются классическим веб-сервисом REST, другие - каким-то экзотическим протоколом, это действительно зависит от поставщика.

  • Какой отзыв / подтверждение предоставляется (синхронизация / асинхронность)

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

  • Вероятно ли добавить новые конечные точки [даже если это так, нужно ли вообще абстрагироваться]

Да, на самом деле наше приложение растет, и мы, вероятно, хотим иметь возможность добавлять нового провайдера, но это соотношение примерно 1 или 2 в год.

Трент
источник
22
Уолтер, Гнат, Гбджаанб, Роберт Харви, Торстен Мюллер кажутся ленивыми людьми; Я не вижу причин, по которым этот вопрос был закрыт из-за одного из следующих аргументов: «двусмысленный, расплывчатый, неполный, слишком широкий или риторический». Вопрос дизайна не может быть простым вопросом, потому что он включает в себя очень много вещей, хотя я и думал, что уровень этого сайта позволял обсуждать такое сложное решение с настоящим профессионалом.
Трент
Задавайте вопросы, но не задавайте вопросы! :) Да, иногда я тоже не понимаю менталитет модов.
Mrchief
upvotes и мнения показывают, насколько этот вопрос актуален .... если бы модераторы поняли бы !!!
NoobEditor
Использование RabbitMQ - правильный подход к этой проблеме. Мне задали очень похожую проблему в одном из интервью с моей БОЛЬШОЙ компанией, и я боролся с наилучшей отказоустойчивой моделью издателя / подписчика. В конце мне сказали правильный ответ. RabbitMQ. Похоже, они решили проблему, используя его. Надеюсь, это поможет!!!
AkD

Ответы:

16

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

Например, ваши нефункциональные требования в отношении масштабируемости довольно неоднозначны. Это может снять большую умственную нагрузку, если вы поместите реальные цифры в вашу систему. Например,

  • Сколько сообщений в секунду вы отправляете (Определите текущие / начальные уровни, определите максимальный уровень, который система должна обработать перед перепроектированием)
  • Какие аппаратные ограничения есть у системы (память, процессор и т. Д., Доступные для системы)
  • Как будет масштабироваться оборудование (например, добавление дополнительных серверов, облачные вычисления и т. Д.)

Теперь, когда у вас все в порядке, вы можете настроить некоторые тесты, чтобы убедиться, что проектирование / архитектура систем способна удовлетворить ваши нефункциональные требования.

Что касается бизнес / функциональных требований отправки уведомлений / сообщений, могут помочь следующие подсказки (если вы предоставите больше информации, я могу добавить к этому ответу):

Определить источники уведомлений

  • Какие языки / системы будут генерировать уведомления
  • Знает ли генератор получателей сообщения (?) Или они предоставляются какими-либо другими средствами (т. Е. Бизнес-правила для определенных типов оповещений переходят к определенным получателям)
  • Существуют ли бизнес-правила для добавления CC / BCC / Read квитанций
  • Известен ли генератору тип отправляемого им сообщения (например, SMS / электронная почта) или он основан на получателе
  • Требует ли генератор подтверждения отправки / получения / чтения сообщений (асинхронная или синхронная отправка)
  • Существуют ли требования для хранения истории источников / получателей сообщений (как долго?)

Определить конечные точки уведомления

  • Какие сервисы используются для отправки сообщений
  • Какой отзыв / подтверждение предоставляется (синхронизация / асинхронность)
  • Вероятно ли добавить новые конечные точки [даже если это так, нужно ли вообще абстрагироваться]

Я не решаюсь привести конкретный пример архитектуры, поскольку он будет сильно зависеть от факторов; но часто самые простые системы сообщений включают в себя базовую очередь в памяти / приложении, без SQL, на диске или в реляционной базе данных. Затем отдельный процесс (или несколько отдельных процессов, если они распределены) могут опрашивать очередь на предмет их типов сообщений [т.е. задание cron]; и отправлять по мере необходимости.

Это также может быть улучшено с помощью некоторых основанных на push-методах (например, PostgreSQL NOTIFY / LISTEN), если существует требование, чтобы сообщения отправлялись немедленно.

Преимущество простой очереди заключается в том, что системе, генерирующей сообщение, не нужно много работать, а систему обработки можно сбалансировать на основе требований к оборудованию / производительности.

Nathan-м
источник
Большое спасибо за ваш подробный ответ, который на самом деле помогает мне иметь более четкие идеи. Я отредактировал свой ответ, чтобы ответить на вопросы, которые вы подняли.
Трент
-2

Рассматривали ли вы шаблон дизайна flyweight для ваших объектов уведомлений? Я не слишком уверен в этом, так как я никогда не реализовывал шаблон, но я помню, что он предполагает разделение некоторого состояния между объектами flyweight. Я также думаю, что члены с большей избыточностью оказали большее влияние, если бы их разделяли. Это зависит от того, отправляете ли вы несколько сообщений нескольким людям или наоборот.

Christoph
источник