Отправка SMTP электронной почты с высокой скоростью в .NET - PullRequest
8 голосов
/ 26 апреля 2010

У меня есть служба .NET, которая обрабатывает очередь в фоновом потоке и из элементов в очереди отправляет большое количество небольших сообщений электронной почты с очень высокой скоростью (скажем, 100 сообщений в секунду, если это даже возможный). В настоящее время я использую SmtpClient.Send(), но боюсь, что это может снизить производительность.

Каждый вызов Send() проходит полный цикл открытия сокета, выполнения диалога SMTP (HELO, MAIL FROM, RCPT TO, DATA) и закрытия сокета. В псевдокоде:

for each message {
  open socket
  send HELO
  send MAIL FROM
  send RCPT TO
  send DATA
  send QUIT
  close socket
}

( Редактировать : Это утверждение о SmtpClient.Send() на самом деле неверно, как я объяснил в своем ответе.)

Я думаю, что следующий псевдокод будет более оптимальным:

open socket
send HELO
for each message {
  send MAIL FROM
  send RCPT TO
  send DATA
}
send QUIT
close socket

Должен ли я беспокоиться о производительности SmtpClient.Send() при высокой скорости отправки электронной почты? Какие есть варианты оптимизации производительности?

Ответы [ 3 ]

7 голосов
/ 27 апреля 2010

Класс SmtpClient кэширует соединения SMTP-сервера за кулисами. Повторный вызов SmtpClient.Send() для отправки нескольких сообщений на один и тот же SMTP-сервер эффективно выполнит псевдокод во втором примере.

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

Я провел несколько элементарных тестов и обнаружил, что это может повысить производительность на целых 100%. Однако оптимальное количество одновременных подключений и фактическое повышение производительности, вероятно, очень сильно зависят от SMTP-сервера. Одним из способов расширить эту идею является подключение к нескольким SMTP-серверам.

2 голосов
/ 26 апреля 2010

Создайте почтовый сервер, который отправляет письма асинхронно, используя пул потоков или что-то еще Таким образом, вы можете «запустить и забыть» свои электронные письма на сервере и позволить им беспокоиться об их отправке. Настройте его на несколько потоков или более, и он сможет быстро перебирать электронные письма.

0 голосов
/ 26 апреля 2010

Процесс отправки электронной почты с использованием SMTP указан (изначально) в RFC 821 . С тех пор было множество обновлений и дополнений, но основной протокол остается прежним. Вам необходимо начать каждую транзакцию с помощью команды HELO, а затем добавить информацию об отправителе, получателях и т. Д. Если вы отправляете одно и то же сообщение всем получателям, вы можете добавить несколько получателей в одно сообщение. Однако, если текст сообщения отличается для каждого получателя, я думаю, что вам нужно будет отправить отдельные сообщения каждому, что означает отдельную транзакцию для каждого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...