Как отправить письмо более чем 15000 получателям? - PullRequest
11 голосов
/ 28 мая 2011

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

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

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

                MailMessage objEmail = new MailMessage();
                objEmail.To =to;
                objEmail.From = "Support@xyz.com";
                //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) Каков максимальный лимит для отправки почты за раз. Значит, сколько значений мы можем присвоить в строке, содержащей emailids?

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

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

Заранее спасибо.

Ответы [ 3 ]

10 голосов
/ 28 мая 2011

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

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

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

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

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

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

В сторону: убедитесь, что ваши получатели каким-то образом запросили или иным образом ожидают эти электронные письма. Рассылка спама незаконна, а наказание сурово.

Ресурсы

Пожалуйста, ознакомьтесь с этими вопросами:

3 голосов
/ 28 мая 2011

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

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

0 голосов
/ 28 мая 2011

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

Я собираюсь использовать 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, но в зависимости от скорости, с которой вы хотите, чтобы ваши электронные письма отправлялись, вы можете ускорить столько агентов или потоков, сколько вам нужно, чтобы обрабатывать электронные письма параллельно.
  • Приоритет будет гарантировать, чтоесли вам нужно отправить высокоприоритетное письмо, полная очередь не будет проблемой.например, если вы хотите отправить все свои электронные письма таким образом, отправка электронного письма с восстановлением пароля или регистрации не будет отложена только потому, что очередь заполнена, если она имеет более высокий приоритет.

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

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

...