Lexxtor
@Lexxtor
PHP, Yii2, Android

Как разослать очередь писем несколькими потоками?

Делаю рассылку писем.
Сделал очередь в виде таблицы в MySql. В таблице есть поля: id и status.
У status могут быть такие значения: 'awaits','sending','sended','error','delivered','opened','clicked'.

Как грамотно сделать рассылку писем из этой очереди, чтобы она могла работать в несколько потоков?

Пока что придумал такое решение:
Cron или что-то другое, максимально часто запускает PHP скрипт, который делает запрос:
SELECT * FROM mail WHERE status='awaits' ORDER BY id LIMIT 10
потом берет из результата min и max id и делает
UPDATE  mail SET status='sending' WHERE id >= 5 AND id <= 14

Таким образом поток пометит порцию писем, чтобы другой поток её не взял. Эти 2 запроса делать внутри транзакции, чтобы в период между ними эти же данные не взял другой поток.
Потом эти 10 писем отсылаются их статус в БД меняется на 'sended' и поток завершается.
Если рассылать придется много, то вместо крона использую то что сможет запускать одновременно по несколько потоков, а не максимум 1, раз в минуту.

Если будете предлагать rabbitMQ, то объясните что это и в чем суть его работы.
  • Вопрос задан
  • 199 просмотров
Пригласить эксперта
Ответы на вопрос 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Сначала
SET @id := 0;
UPDATE `mail` 
  SET `status` = `sending` 
  WHERE (@id := `id`) AND `status` = 'awaits' 
  ORDER BY `id`
  LIMIT 1;

Затем
SELECT * FROM `mail` WHERE `id` = @id;
Скрипт можно запускать из крона раз в минуту, но сделать в нём цикл. Пока есть задания на отправку скрипт не должен завершаться. Тогда количество скриптов будет расти каждую минуту пока всё не будет отправлено.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы