Как отправить почту более чем 15 000 получателям?

Мы используем asp.net 3.5 с С#. Мы должны создать мощный модуль почтовой программы. Этот модуль может отправлять более 15000 получателей или, короче говоря, все записи в СУБД. Я хотел бы задать несколько вопросов.

1) У нас есть код, который отправляет почту одному получателю. Как мы отправим письмо нескольким получателям. Я попробовал с нашим кодом добавить более одного идентификатора электронной почты на ",", но он отправляет только первый идентификатор электронной почты. Вот пример кода

 public bool Mail(string to, string subject, string body)
        {
            try
            {

                MailMessage objEmail = new MailMessage();
                objEmail.To =to;
                objEmail.From = "[email protected]";
                //objEmail.Priority =priority

                objEmail.Subject = subject;

                objEmail.Body = body;

                //enable the Html tag...

                objEmail.BodyFormat = MailFormat.Html;
                objEmail.Priority = MailPriority.High;

                SmtpMail.SmtpServer = "localhost";

                try
                {
                    SmtpMail.Send(objEmail);
                    return true;

                }
                catch(Exception ex)
                {
                    string error = ex.StackTrace;
                    return false;
                }
            }
            catch
            {
                return false;
            }
        }

2) Каков максимальный предел для отправки почты за раз. Сколько можно присвоить значение в строке, содержащей электронные письма?

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

Давайте предложим, что это лучший способ сделать это.

Спасибо заранее.

Ответ 1

Не используйте System.Web.Mail. Используйте System.Net.Mail. Смотрите blog.

System.Web.Mail устарел и не рекомендуется.

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

Если все, что вам нужно, - это дешевый почтовый сервер, который вы можете добавить в очередь на электронную почту, и сервер будет просто перебирать их и отправлять, а затем Amazon SES стоит посмотреть. Если вы хотите больше инструментов управления пользователями и управления кампаниями, то MailChimp или JangoMail могут быть вашими лучшими опциями.

Amazon SES определенно самый дешевый, поскольку вы платите только за то, что используете. В среднем я провожу 4 доллара в месяц.

Все они предоставляют API, которые вы можете использовать в своем коде.

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

Ресурсы

Пожалуйста, также проверьте следующие вопросы:

Ответ 2

Помимо ответа Chevex: если вы отправляете электронное письмо нескольким получателям, подумайте об использовании BCC. Если вы используете TO и CC, каждый получатель увидит адреса электронной почты других получателей, которые они могут не оценить.

Если вы хотите перевернуть свой собственный модуль sendmail вместо использования одной из доступных служб, посмотрите на этот вопрос для некоторых подходов к выполнению более длинных фоновых задач в ASP.NET: Лучший способ запустить фоновое задание в веб-приложении ASP.Net, а также получить обратную связь?

Ответ 3

Это моя рекомендация, и она использует базу данных для управления рабочей нагрузкой.

Я буду использовать SQL Server в качестве примера здесь, потому что это то, что я использовал сам.

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

SendDate
IsSent
ErrorCount
Priority

В какой-то момент вам понадобится запустить поток или процесс, который выполняет фактическую работу, но как это реализовано, это интересный бит.

С SQL Server вы можете написать такой запрос:

DELCARE @now datetime; SET @now = GETDATE();

SELECT TOP (5) * 
FROM OutgoingEmail WITH (ROWLOCK, READPAST, UPDLOCK) 
WHERE SendDate < @now
    AND IsSent = 0 
    AND ErrorCount < 5
ORDER BY Priority
;

READPAST может быть указан только в транзакциях, работающих на уровнях изоляции READ COMMITTED или REPEATABLE READ. Вы устанавливаете уровень изоляции при установлении нового соединения.

Теперь, что произойдет, когда вы используете объект SqlCommand для создания DataReader, SQL Server заблокирует эти строки. Никакие другие экземпляры не смогут их получить. Это означает, что теперь у вас есть рабочая очередь для исходящей электронной почты. Однако важно помнить, что вы должны держать соединение открытым, пока выполняете свою обработку, иначе блокировка будет выпущена.

Несколько замечаний.

  • Вы получаете кучу строк, и вы отправляете их. Если вам удастся установить бит IsSent
  • Если вы вышли из строя (исключение выбрано где-то), вы не отбрасываете письмо, которое вы вызываете ErrorCount. Вы не удаляете его, просто поднимите счет. Это важно, потому что, если по какой-то причине электронная почта содержала входные данные (в отличие от проблемы со связью в сети), она могла бы терпеть крах для отправки клиентов, и это называется отравлением, и это предотвратит сбой данных с ваших клиентов-отправителей. Поэтому вы должны игнорировать электронную почту с высоким ErrorCount
  • Вы также можете удалить расписание расписания и переместить SendDate вперед, чтобы не прерывать то же самое все время от времени.
  • Узким местом будет класс SmtpClient, но в зависимости от скорости отправки ваших писем вы можете развернуть столько агентов или потоков, сколько необходимо для обработки писем параллельно.
  • Приоритет гарантирует, что если вам нужно отправить высокоприоритетный адрес электронной почты, полная очередь не будет проблемой. например если вы хотите отправить все свои электронные письма таким образом, отправка пароля reset или регистрация электронной почты не будет отложена только потому, что очередь заполнена, если она имеет более высокий приоритет.

Одна вещь, которую следует отметить, это то, что при возникновении ошибок причина неизвестна, я видел, что случайная сетевая проблема вызывает отправку сообщений электронной почты. Что обычно будет с этим подходом, так это то, что электронное письмо будет отправлено позднее, когда сетевое подключение или SMTP-сервер снова будут подключены к сети. Вы также можете добавить дополнительные метаданные, чтобы не отправлять более одного письма пользователю, пытающемуся reset его или ее пароль (только потому, что по какой-то неизвестной причине электронные письма не отправляются прямо сейчас).

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