Пишем свою систему рассылки

Рассылка — это то, что позволяет пользователю, оставившему однажды свой email, получать информацию быстро и качественно. Но сделать рассылку нужно тоже грамотно, чтобы избежать некоторых проблем:

  1. Большой нагрузки на сервер
  2. Обрыв рассылки на середине списка
  3. Большое время ожидания завершения рассылки.
  4. Если почтовый сервер «лег»,  то письмо к адресату просто теряется

Чтобы этого избежать, предлагаю свое решение. Инструменты: mysql и любой язык программирования.Здесь специально не будет готового решения, так как:

  • код будет отличаться для каждого отдельного сайта
  • программистам надо уметь делать что-то самим

Итак, приступим —  самое важное на мой взгляд это придумать архитектуру нашего «рассыльщика» и грамотно спроектировать базу.

Mysql составляющая.

Тут у нас будет три таблицы: база подписчиков, сама рассылка (текст, заголовок), очередь на отправку.

Подписчики

Имя поля Тип данных Описание
id_user INTEGER Идентификатор подписчика. Автоинкриментное поле
name VARCHAR(255) Имя подписчика
email VARCHAR(255) Email подписчика

Рассылки

Имя поля Тип данных Описание
id_subscribe INTEGER Идентификатор подписки
subject VARCHAR(255) Тема письма
letter TEXT Текст или шаблон письма

Очередь отправки

Имя поля Тип данных Описание
id_subscribe INTEGER Идентификатор подписки. Внешний ключ
id_user INTEGER Идентификатор подписчика. Внешний ключ
attempt_count INTEGER Поле указывающее сколько попыток отправить данное письмо уже было

Теперь алгоритм работы на языке программирования, им может быть php

  1. Создаем функцию, которая при создании нового письма на рассылку ставит всех пользователей в очередь
    1. Вставляем запись с рассылкой
    2. Получаем id_subscribe для новой записи
    3. Получаем идентификаторы всех пользователей
    4. Вставляем это все а таблицу отправки(пару идентификатор рассылки/идентификатор пользователя.
  2. Создаем функцию отправки письма пользователю
    1. Выбираем первые 30 записей отсортированных по attempt_count1
    2. Получаем данные подписчиков, текст и тему письма.
    3. Отправляем письмо. Отправлять нужно отдельно каждому пользователю, а не ставить в копию по 10 человек. Итак, если письмо отправлено, удаляем запись из таблицы, в обратном случае прибавляем к полю attempt_count + 1
    4. Удаляем записи, число попыток отправки в которых перевалило 32
  3. Создаем новое cron задание, которое будет каждую минуту вызвать скрипт с функционалом из пункта 23.

Вы заметили, что в пункте 2 и 3 есть сноски, ниже я их расшифровываю

1 — 30 это примерное число, все зависит от мощностей сервера и величины очереди на отправку, но отправлять больше одного письма в секунду я бы не советовал
2 — 3 также примерное число, но делать больше попыток я бы не стал, особенно если другие письма отправились,а это не хочет — возможно просто несуществующая запись.
3 — зависит от величины рассылки, в одном проекте использовался алгоритм, когда каждые 5 минут уходило 100 писем.

Для совершенствования нашей системы можно добавить функционал, который не позволял бы запускать следующий cron job пока не завершился предыдущий.

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