2014-04-27 4 views
1

Мой вопрос теоретический. У меня есть база данных с электронными письмами. Для каждого письма я сохраняю желаемое время отправки (как временную метку UNIX) и содержимое электронной почты (отправитель, получатель, субъект, тело и т. Д.). Планируется большое количество электронных писем. Вот как я хотел отправить электронные письма до сих пор: У меня был бы рабочий процесс или сервер, который периодически запрашивает базу данных для «просроченных» электронных писем на основе временных меток. Затем он отправляет эти сообщения электронной почты и, в конце концов, удаляет их из БД.Как отправлять запланированные электронные письма?

Я начал думать о двух вещах:

  • Что делать, если работник умирает, когда он послал по электронной почте, но не удален из базы данных? Если я перезапущу работника, электронное письмо будет отправлено снова.
  • Как это сделать, если у меня действительно большое количество сообщений электронной почты , и поэтому я запускаю нескольких сотрудников? Я могу отметить e-mail в базе данных как «отправляется», но как я могу начать отправку, если умирает ответственный работник ? Я имею в виду, что я не буду знать, умер ли рабочий или , это так медленно, что он по-прежнему отправляет сообщения. Я предполагаю, что не могу получить уведомление о том, что рабочий умер, поэтому я не могу повторно отправить электронные письма, которые он не смог отправить.

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

Как это делается?

+0

Есть ли у кого-нибудь идеи? –

ответ

1

Я бы на самом деле использовать флаг на каждой записи электронной почты в базе данных:

Ваш рабочий (или кратные) обновить старую запись с их уникальным рабочим ID (например, PID или комбинацию IP/PID).

Пример для Oracle SQL:

update email set workerid = 'my-unqiue-worker-id' where emailid in (
    select emailid from email where 
    rownum <= 1 and 
    duetime < sysdate and 
    workerid = null 
    order by duetime 
) 

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

Затем вы выбираете все записи с:

select * from email where workerid = 'my-unique-worker-id' 

, которые будут либо 0 или 1 запись. Если он равен 0, почтовой почты нет.

Если вы закончили отправку электронной почты вы Установите workerid = 'some-invalid-value' (или вы используете другой флаг-колонки, чтобы отметить прогресс. Таким образом, он не получает подобран следующим рабочим.

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

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

+0

Спасибо за помощь! Таким образом, нет возможности сделать 100% уверенным, что электронное письмо отправляется и не отправляется дважды. Я продолжу этот путь! –

Смежные вопросы