Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hw 2 #11

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open

Hw 2 #11

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 61 additions & 1 deletion notificator/software_architecture_document.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,70 @@

## Целевая архитектура

### Предполагаемая нагрузка:

В задании не указана ожидаемая нагрузка, поэтому напишу фанфик.

Нам известно, что пользователями сервиса будут другие подсистемы. Допустим, изначально такая подсистема будет всего одна, но с достаточно большим числом пользователей -- 100к месячных пользователей. Сервис шлет оповещения каждому из них по 10 раз в день в рабочие часы, особенно активно используя пуши и имейл. 100к умножаем на 10 и делим на число секунд в рабочих часах, 1млн / (8 * 60 * 60) -- получается около 34 rps и например 50 rps в пике.
Через полгода собираются заехать еще два сервиса со сходным числом пользователей. Постараемся подготовиться к нагрузкам втрое больше ~150 rps.

Для пользователей мы должны хранить настройки оповещений и контактные данные. Настройки оповещений скорее всего будут меняться не очень часто, а вот читать эти настройки нужно будет при каждом запросе на отправку оповещения, значит, система будет Read intensive.
### Диаграмма контекста (C1):
![C1](static/c1.svg)

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

### Диаграмма контекста (C2):
> Вам нужно добавить C2 и C3 диграммы системы. Если при переходе от уровня к уровню были приняты архитектурно-значимые решения (выбор технологии для хранилища, дополнительные дизайн-паттерны и тд.) нужно добавить ссылки на соответствующие ADR.

![C2](static/c2.svg)

Система будет состоять из следующих модулей:

* API Gateway -- входная точка для клиентов системы. Осуществляет аутентификацию и роутинг запросов. Для этого используем Nginx.
https://nginx.org/en/docs/http/ngx_http_auth_request_module.html#auth_request
https://nginx.org/en/docs/http/ngx_http_proxy_module.html

* Load Balancer -- Nginx https://nginx.org/en/docs/http/load_balancing.html

- Golang сервер управления отправкой сообщений, который умеет
- получать сообщения от других систем через системный интерфейс
- позволяет отправлять сообщение по всем каналам группе клиентов
- позволяет отправлять сообщение адресно в каждый канал связи конкретным адресатам
- добавляет сообщения в очередь на отправку согласно настройкам каналов
- менять настройки отправления сообщений в реальном времени
Документация по использованию network API в go https://pkg.go.dev/[email protected]

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

- Очередь сообщений RabbitMQ для отправки в разных каналах. Позволяет обрабатывать сообщения в порядке очереди и учитывать пропускные лимиты каналов.
https://learn.microsoft.com/en-us/azure/architecture/patterns/queue-based-load-leveling
https://www.rabbitmq.com/queues.html

- Компоненты для предобработки и отправки сообщений:
- SMS:
предусматривает ограничение количества символов в СМС
- Email:
предусматривает возможность попадания email в спам
- Push:
предусматривает возможность отправки пушей на разные платформы (iOS, Android, Web)
Вряд ли есть потребность целиком реализовывать эти сервисы, можно взять внешние решения и добавить адаптеры для них.

### Architecture Decision List:
|ID|Дата|Статус|Имя|Решение|
|---|---|---|---|---|
|[ADR-1](static/adr/adr-1.md)|08.10.23|Принято|Полина Шестакова|Модульная архитектура|
|[ADR-2](static/adr/adr-2.md)|08.10.23|Принято|Полина Шестакова|Сервер для управления отправкой сообщений|
|[ADR-3](static/adr/adr-3.md)|08.10.23|Принято|Полина Шестакова|База данных для хранения настроек отправки|
|[ADR-4](static/adr/adr-4.md)|08.10.23|Принято|Полина Шестакова|Брокер сообщений|
|[ADR-5](static/adr/adr-5.md)|08.10.23|Принято|Полина Шестакова|API Gateway и Load Balancer|
|[ADR-6](static/adr/adr-6.md)|08.10.23|Принято|Полина Шестакова|Логирование и мониторинг|

### Диаграмма компонентов (C3):

![C3](static/c3.svg)
### Критерии оценки прототипа:

1. Оповещения доходят до адресатов по всем поддержанным каналам
2. Настройки оповещений позволяют ограничивать отправку
3. Микросервисная архитектура позволяет легко отключать и включать каждый из каналов
4. Система выдерживает ожидаемую нагрузку, включая пиковую
32 changes: 32 additions & 0 deletions notificator/static/adr/adr-1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#### ID: ADR-1

#### Дата: 08.10.23

#### Статус: Принято

#### Участники:
Полина Шестакова

#### Решения:
Модульная архитектура, которая разделяет задачи и позволяет легко расширять функциональность.

Для контейнеризации компонентов используем Docker. Это популярное решения с большой поддержкой коммьюнити. В дальнейшем для оркестрации системы может использоваться Kubernetes, но на данный момент это необязательно.

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

#### Контекст:
Нам необходимо разработать систему электронной почты, которая позволяет отправлять сообщения по разным каналам связи -- смс, пуш, имейл. Система должна предусматривать возможность интеграции с другими системами с помощью API. Также система должна принимать от пользователя системы настройки по каждому каналу связи для рассылки уведомлений (вкл./выкл., адрес/номер/логин) и учитывать их при последующих рассылках.

#### Последствия:

#### Положительные:
* позволяет легко добавлять новые функции, например, новые каналы связи
* позволяет масштабировать систему при росте нагрузки, добавляя новые сервера для отправки сообщений
* отказоустойчивость системы - выход из строя одного компонента не обязательно приводит к полной остановке системы

#### Отрицательные:
* требует больше времени на разработку
* требует больше ресурсов для сопровождения и поддержки
* нужна команда разработки с опытом разработки микросервисной архитектуры


33 changes: 33 additions & 0 deletions notificator/static/adr/adr-2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#### ID: ADR-2

#### Дата: 08.10.23

#### Статус: Принято

#### Участники:
Полина Шестакова

#### Решения:
Сервер для управления отправкой сообщений
Выбираем golang

Альтернативные решения:
python + django -- более распространенный, но менее производительный
nodejs + express -- поддерживает асинхронное выполнение из коробки, но менее производительный и не поддерживает "настоящую" многопоточность. менее распространенный чем go и python
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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


#### Контекст:
Необходимо написать сервер, который будет получать сообщения от других сервисов и управлять их рассылкой по заданным в базе данных каналам, используя для этого брокер сообщений.

#### Последствия:

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

#### Отрицательные:
* отсутствие стандартных библиотек для работы с базами данных
* у команды небольшой опыт разработки на этом языке, потребуется дополнительное время на обучение и наем новых сотрудников
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Молодец! Как я отмечал в комментариях выше, это действительно может быть проблемой

* довольно новый язык, не для всех задач есть готовые библиотеки
29 changes: 29 additions & 0 deletions notificator/static/adr/adr-3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#### ID: ADR-3

#### Дата: 08.10.23

#### Статус: Принято

#### Участники:
Полина Шестакова

#### Решения:
База данных для хранения настроек отправки
Выбираем PostgreSQL

Альтернативные решения:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

MySQL -- легче в настройке, но имеет меньше инструментов для работы с данными.
MongoDB -- NoSQL база данных. Может быть полезна, если в будущем понадобится хранить большое количество данных, но в нашем случае структура у данных достаточно жесткая, чтобы использовать SQL базу данных
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

в описании есть ссылка на жесткую структуру, которая не обозначена в adr и основном документе


#### Контекст:
Нужно хранить настройки отправки сообщений для каждого пользователя и канала. Некоторые пользовательские данные будут забираться из других подсистем. По описанию задачи выглядит так, что данные достаточно структурированы -- у каждого пользователя есть набор контактных данных и настройки оповещений.

#### Последствия:

#### Положительные:
* бесплатное open source решение
* масштабируемость
* большое число фичей и инструментов для работы с данными

#### Отрицательные:
* сложность настройки
33 changes: 33 additions & 0 deletions notificator/static/adr/adr-4.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#### ID: ADR-4

#### Дата: 08.10.23

#### Статус: Принято

#### Участники:
Полина Шестакова

#### Решения:
Брокер сообщений
Выбираем RabbitMQ

Альтернативные решения:
Kafka - не реализует маршрутизацию сообщений из коробки
ActiveMQ - сложнее в использовании, а документация не такая подробная, как для RabbitMQ.

#### Контекст:
Нужна очередь для отправки сообщений, чтобы
- не блокировать сервер отправки сообщений в случае, если какой-то из каналов связи недоступен
- учитывать пропускные лимиты каналов связи
- обеспечить переотправку сообщений

#### Последствия:

#### Положительные:
* прост в настройке и использовании
* хранит очередь сообщений
* может сохранять очередь даже в случае перезапуска процесса

#### Отрицательные:
* нужно получить дополнительную экспертизу по использованию этого инструмента
* сложно реализовать горизонтальное масштабирование
27 changes: 27 additions & 0 deletions notificator/static/adr/adr-5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#### ID: ADR-5

#### Дата: 08.10.23

#### Статус: Принято

#### Участники:
Полина Шестакова

#### Решения:
API Gateway и Load Balancer
Выбран Nginx, так как его можно использовать в качестве API Gateway для маршрутизации и балансировки нагрузки между микросервисами.

#### Контекст:
Так как в качестве архитектуры были выбраны микросервисы, понадобится балансировщик нагрузки. Также нужен API Gateway для обеспечения безопасности и аутентификации пользователей -- других микросервисов.
В качестве метода аутентификации можно остановиться на API Key. Для начала список ключей можно хранить прямо в конфигурации шлюза.

#### Последствия:

#### Положительные:
* open source решение
* подробная документация
* легкость масштабирования

#### Отрицательные:
* требует дополнительных затрат на интеграцию и поддержку

29 changes: 29 additions & 0 deletions notificator/static/adr/adr-6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#### ID: ADR-6

#### Дата: 08.10.23

#### Статус: Принято

#### Участники:
Полина Шестакова

#### Решения:
Логирование и мониторинг
Для получения логов можно использовать syslog, а для визуализации и алертов -- grafana.

Альтернативные решения:
Sentry -- популярный инструмент для логирования и алертов, хороший запасной кандидат.

#### Контекст:
Нужно собирать, хранить и обрабатывать логи работы сервиса.
Например, в случае, если отправка сообщения не увенчалась успехом даже после максимального числа ретраев, хочется сразу же понимать, насколько это частый случай, нет ли проблемы с определенным пользователем, каналом или инстансом сервиса.

#### Последствия:

#### Положительные:
* удобный интерфейс для просмотра логов

#### Отрицательные:
* дополнительные затраты на интеграцию логирования и алертов
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

скорее всего нужна еще инфраструктура для хранения логов и данных, а это опять же поддержка и сопровождение

но обычно это решается централизовано для команды/компании

* затраты на создание инфраструктуры для хранения логов
* затраты на поддержку и сопровождение инфраструктуры
Loading