-
Notifications
You must be signed in to change notification settings - Fork 0
bonifazy/mailing
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Сервис рассылки сообщений клиентам по заданным параметрам фильтрации (номер телефона, тег) на сторонний сервер https://probe.fbrq.cloud/ любым REST- API клиентом. В проекте используются сторонние приложения и фреймворки python3.7 (версии фреймворков заданы принимающей компанией): Django==2.2 - используется панель администратора для визуализации и тестирования моделей Рассылка, Клиент, Сообщение, а также celery tasks results-- список результатов отправки сообщений на сторонний сервер; celery==5.2.3 - celery beat отправляет рабочие функции 'tasks' брокеру сообщений RabbitMQ; django-celery-results==2.3.0 - результаты исполнения функций отправки каждого сообщения; djangorestframework==3.13.1 - REST API сторонним сервисам для создания, изменения и удаления клиентов и рассылок; requests==2.27.1 - отправка POST запроса на сторонний сервис https://probe.fbrq.cloud/ для передачи сообщения; rabbitmq==3.9.14 - брокер сообщений, принимающий и обрабатывающий 'tasks' от Celery Beat. 1. Установка. Весь проект рекомендуется запускать из виртуального окружения для избежания несовместимости версионной зависимости сторонних пакетов и приложений Python. Скачайте репозиторий с сервера Github: git clone https://github.com/bonifazy/mailing.git Установите Python- фреймворки: pip install -r requirements.txt Настройте Django окружение для работы панели администратора и работы REST API со сторонними сервисами: Произведите миграции основного приложения 'mailing', установите миграции всего проекта, перенесите статические файлы в общую папку и создайте профиль администратора Django: python manage.py makemigrations mailing python manage.py migrate python manage.py createsuperuser python manage.py collectstatic Установите актуальный JWT- токен для работы с сервером https://probe.fbrq.cloud/ в файл: project/secret_key.py Установите брокер сообщений RabbitMQ: для Linux Ubuntu/ Debian: обновите репозиторий менеджера пакетов 'apt-get', установите приложение и запустите демон сервиса RabbitMQ в системе c правами sudo: sudo apt-get update sudo apt-get install rabbitmq-server sudo systemctl start rabbitmq-server для MacOS: обновите репозиторий менеджера пакетов 'homebrew', установите RabbitMQ, пропишите дополнительные пути поиска для запуска демона приложения в автозагрузку системы, запустите демон сервиса RabbitMQ: brew update brew install rabbitmq echo -e "#add path for RabbitMQ\nexport PATH=\"\$PATH:/usr/local/sbin\"\n" >> ~/.bashrc brew services start rabbitmq для Windows: https://github.com/rabbitmq/rabbitmq-server/releases/download/v3.9.14/rabbitmq-server-3.9.14.exe Подробнее по установке и запуску RabbitMQ: https://rabbitmq.com 2. Использование сервиса. 2.1. Запуск среды исполнения. Запустите Django- сервер: python manage.py runserver Запустите Celery с флагом '--beat' с использованием планировщика: celery -A project worker -l info --beat 2.2. Создание клиента и рассылки. В проекте по принципу Rest API реализована коммуникация обмена данными между сторонними сервисами- клиентами и моделями базы данных самого приложения. Через API можно посмотреть, создать, изменить и удалить клиента или рассылку. Эндпоинт клиента: http://127.0.0.1:8000/api/client/ Эндпоинт рассылки: http://127.0.0.1:8000/api/mailing/ Основная работа операций CRUD с клиентом и рассылкой находится в файле: mailing/views.py Методы создания и изменения поддерживают режим частичного обновления параметров. В модели 'Клиент' реализованы следующие поля: 'number' - номер телефона; 'code' - код оператора; 'tag' - тег, который будет ассоциирован рассылкой с этим клиентом; 'zone' - часовая зона клиента; из которых обязательны для создания модели 'Клиента': 'number', 'tag', 'zone'. 'code' создается (или перезаписывается, если задан пользователем) автоматически при валидации создания модели в: mailing/models.py Доступно как полное, так и частичное обновление полей модели, поэтому методом PUT можно обновить как конкретное поле, так и все поля клиента сразу. В модели 'Рассылка' для создания новой рассылки все поля обязательны для заполнения: 'starts_at' - время начала рассылки 'expired_at' - время окончания рассылки 'text' - текст рассылки 'filter' - (код оператора, тег) для фильтрации отправления сообщений Как и в модели 'Клиент', доступно полное и частичное обновление полей модели. 2.3. Основная механика создания рассылки, создания сообщений и их отправка. Рабочий метод: mailing.views.MailingView.post() Во время создания рассылки находятся все клиенты по указанному фильтру и по найденным клиентам сразу создаются сообщения со статусом 'new'. Сообщения создаются сразу для исключения случаев отправки большого количества сообщений в малых промежутках времени доставки (1 рассылка 10_000 клиентам за 1 мин в будущем, к примеру. Для того, чтобы не тратить время на создание сообщений в критичных временных диапазонах, сообщения создаются сразу при создании рассылки). Если указанное время начала рассылки меньше, чем время в данный момент и время окончания еще не наступило, вызывается метод mailing.tasks.send() для отправки сообщений. Если указано время начала рассылки в будущем, сообщения сохраняются со статусом 'new' и метод отправки сообщений mailing.tasks.send() не вызывается. В дальнейшем, планировщик Celery Beat с периодичностью, заданной в настройках Celery (projects/settings.py), мониторит время отправки, и при валидности временного интервала рассылки, захватывает сообщения для отправки, пытаясь отправить каждое сообщение. Метод mailing.views.MailingView.put() обновляет любое из полей конкретной рассылки. Если обновлено поле старта запуска рассылки, проверяется актуальность отправки. Если временные условия соблюдены, рассылка отправится так же, как и в методе post(), сразу же во время создания самой рассылки. 2.4. Отправка сообщений с помощью Celery/ Celery Beat + RabbitMQ. Метод поиска и захвата сообщений: mailing.tasks.send() Метод отправки сообщения: mailing.tasks.send_message() 2.4.1. Поиск и группировка сообщений для отправки. Метод send() вызывается либо из mailing/views.py, когда известно id конкретной рассылки и время отправки и окончания рассылки валидны, либо из планировщика заданий Celery Beat, когда захватываются все новые сообщения любых рассылок, подходящие условиям временных интервалов. Для уменьшения нагрузки на принимающий сервер, сглаживания пиковой нагрузки в моменты отправления больших объемов сообщений (более 10_000 сообщений сразу, к примеру), все полученные сообщения группируются в рабочие группы Celery.task.group, затем отправляются с небольшой задержкой между запуском очередной порции группы сообщений методом send_message(). mailing.tasks.CHUNK - параметр количества отправляемых сообщений в одной группе celery.task.group mailing.tasks.SLEEP - параметр временного промежутка между отправляемыми группами celery.tasks 2.4.2. Отправка сообщения. Метод send_message() по id находит сообщение, формируя POST запрос на сторонний сервер https://probe.fbrq.cloud/ с данными сообщения, связанного клиента и связанной рассылки. В случае успешной отправки устанавливается статус сообщения 'sent'-- отправлен. В случае неудачной отправки, если время отправки рассылки (сообщения) не истекло, статус меняется на 'новый', позволяя в следующий раз обработать это сообщение, допустим, когда принимающий сервер снова начнет стабильно работать. В случае обработки сообщения, если время окончания запуска рассылки (сообщения) истекло, устанавливается статус 'failure', убирая данное сообщения из дальнейшего поиска новых сообщений для отправки. 2.5. Просмотр статистики. Эндпоинт статистики рассылок: http://127.0.0.1:8000/api/mailing/ Эндпоинт конкретной рассылки (пример для id == 1): http://127.0.0.1:8000/api/mailing/1/ Актуальная версия находится в master- ветке проекта: https://github.com/bonifazy/mailing/ Подробная документация OpenAPI (Swagger OAS3.0): http://127.0.0.1:8000/docs/ Дополнительная информация: dkmarchuk@gmail.com t.me/etoSlishkom
About
Сервис рассылки сообщений клиентам по заданным параметрам фильтрации (номер телефона, тег) на сторонний сервер. Web API.