Ich habe einen .NET-Dienst, der eine Warteschlange in einem Hintergrundthread verarbeitet und aus den Elementen in der Warteschlange eine große Anzahl kleiner E-Mail-Nachrichten mit einer sehr hohen Rate sendet (sagen wir 100 Nachrichten pro Sekunde, wenn diese gerade ist) möglich). Derzeit verwende ich SmtpClient.Send()
, aber ich habe Angst davor kann die Leistung beeinträchtigen.
Jeder Aufruf von Send()
durchläuft einen vollständigen Zyklus des Öffnens des Sockets, führt die SMTP-Konversation (HELO, MAIL FROM, RCPT TO, DATA) durch und schließt den Socket. Im Pseudocode:
( Bearbeiten : Diese Aussage über SmtpClient.Send()
ist tatsächlich falsch, wie ich in meiner Antwort erklärt habe.)
Ich würde denken, dass der folgende Pseudocode optimal wäre:
%Vor% Sollte ich über die Leistung von SmtpClient.Send()
besorgt sein, wenn ich E-Mails mit hoher Geschwindigkeit sende? Was sind meine Möglichkeiten, um die Leistung zu optimieren?
Die Klasse SmtpClient
cachiert SMTP-Serververbindungen hinter den Kulissen. Der Aufruf von SmtpClient.Send()
wiederholt, um mehrere Nachrichten an denselben SMTP-Server zu senden, führt den Pseudocode im zweiten Beispiel effektiv aus.
Eine Möglichkeit, die Leistung zu verbessern, besteht darin, mehrere Instanzen von SmtpClient
für mehrere Threads zu verwenden. Anstatt nur eine Verbindung zum SMTP-Server zu haben, wird der Dienst nun viele gleichzeitige Verbindungen haben. Eingehende E-Mail-Nachrichten werden aus der Warteschlange abgerufen und an einen Pool von Arbeitsthreads gesendet, die SmtpClient.Send()
aufrufen, um die Nachricht an den SMTP-Server zu senden.
Ich habe einige rudimentäre Tests durchgeführt und festgestellt, dass dies die Leistung um bis zu 100% verbessern kann. Die optimale Anzahl von gleichzeitigen Verbindungen und die tatsächliche Leistungsverbesserung hängen jedoch wahrscheinlich sehr stark vom SMTP-Server ab. Eine Möglichkeit, diese Idee zu erweitern, besteht darin, sich mit mehreren SMTP-Servern zu verbinden.
Erstellen Sie einen E-Mail-Server, der E-Mails mit einem Threadpool oder etwas asynchron versendet. Auf diese Weise können Sie Ihre E-Mails auf dem Server "feuern und vergessen" und sich darum kümmern, sie alle abzuschicken. Richten Sie es mit ein paar Threads oder mehr ein und es sollte in der Lage sein, E-Mails ziemlich schnell zu versenden.
Der Prozess zum Senden einer E-Mail über SMTP wird (ursprünglich) in RFC 821 angegeben. Seither gab es zahlreiche Updates und Ergänzungen, aber das grundlegende Protokoll ist immer noch das gleiche. Sie müssen jede Transaktion mit einem HELO-Befehl starten und dann die Absenderinformationen, Empfänger usw. hinzufügen. Wenn Sie dieselbe Nachricht an alle Empfänger senden, können Sie mehrere Empfänger in einer Nachricht hinzufügen. Allerdings, wenn der Text der Nachricht für jeden Empfänger unterschiedlich ist, denke ich, dass Sie einzelne Nachrichten an jeden senden müssen, was eine separate Transaktion für jeden bedeutet.