2010-04-26 6 views
8

J'ai un service .NET qui traite une file d'attente sur un thread d'arrière-plan et à partir des éléments de la file d'attente envoie un grand nombre de petits messages électroniques à un très taux élevé (disons 100 messages par seconde si c'est même possible). Actuellement, j'utilise SmtpClient.Send() mais je crains que cela puisse entraver les performances.Envoyer un courrier SMTP à un taux élevé dans .NET

Chaque appel à Send() passe par un cycle complet d'ouverture du socket, en exécutant la conversation SMTP (HELO, MAIL FROM, RCPT TO, DATA) et en fermant le socket. Dans le code pseudo:

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

(Modifier. Cette déclaration sur SmtpClient.Send() est en fait faux comme je l'ai expliqué dans ma réponse)

Je pense que le pseudo-code suivant serait plus optimale:

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

Dois-je être préoccupé par la performance de SmtpClient.Send() lors de l'envoi courriel à un taux élevé? Quelles sont mes options pour optimiser la performance?

+0

ces messages sont-ils généralement les mêmes, mais à des destinataires différents, ou le contenu de l'e-mail est-il différent? –

+0

@Rob Levine: Même destinataire, mais contenu différent. –

+0

À des centaines de seconde? Qui sur Terre veut être enterré sous tant d'e-mail? –

Répondre

7

La classe SmtpClient met en cache les connexions du serveur SMTP en coulisses. Appeler SmtpClient.Send() à plusieurs reprises pour soumettre plusieurs messages au même serveur SMTP exécutera effectivement le pseudo-code dans le deuxième exemple. Une façon d'améliorer les performances peut être d'utiliser plusieurs instances de SmtpClient s'exécutant sur plusieurs threads. Au lieu d'avoir une seule connexion au serveur SMTP, le service aura maintenant de nombreuses connexions simultanées. Les messages électroniques entrants sont extraits de la file d'attente et envoyés à un pool de threads de travail qui appelle SmtpClient.Send() pour envoyer le message au serveur SMTP.

J'ai fait quelques tests rudimentaires et j'ai constaté que cela pouvait améliorer les performances jusqu'à 100%. Cependant, le nombre optimal de connexions simultanées et l'amélioration réelle des performances dépendent probablement beaucoup du serveur SMTP. Une façon d'étendre cette idée est de se connecter à plusieurs serveurs SMTP.

0

Le processus d'envoi d'un courrier électronique à l'aide de SMTP est spécifié (à l'origine) dans RFC 821. Il y a eu de nombreuses mises à jour et ajouts depuis, mais le protocole de base est toujours le même. Vous devez démarrer chaque transaction avec une commande HELO, puis ajouter les informations sur l'expéditeur, les destinataires, etc. Si vous envoyez le même message à tous les destinataires, vous pouvez ajouter plusieurs destinataires dans un même message. Cependant, si le texte du message est différent pour chaque destinataire, je pense que vous aurez besoin d'envoyer des messages individuels à chacun, ce qui signifie une transaction distincte pour chacun.

+1

J'ai découvert que 'SmtpClient.Send()' lorsqu'il est appelé de manière répétée n'ouvre le socket qu'une seule fois, émet une commande EHLO et envoie plusieurs commandes MAIL FROM, RCPT TO et DATA sur la même connexion. –

2

Créez un serveur de messagerie qui envoie des e-mails de manière asynchrone à l'aide d'un pool de threads ou de quelque chose. De cette façon, vous pouvez «tirer et oublier» vos e-mails sur le serveur et vous inquiétez de les envoyer tous. Configurez-le avec quelques threads ou plus et il devrait être capable de fouiller les emails assez rapidement.

+0

C'est exactement ce que nous faisons, sauf que nous semblons avoir quelques problèmes de performance. Ma question porte sur la façon la plus performante à « fire and forget » e-mails à partir d'un service .NET. –

+0

Quels problèmes de performances? Dans ma mise en œuvre, je pourrais envoyer des milliers d'emails par minute. Est-ce qu'il lance des exceptions? Ceux-ci sont incroyablement lents dans le courrier car vous devez souvent attendre l'expiration d'un socket. – Chris

+0

En moyenne, nous envoyons 20 e-mails par seconde, mais de nombreux facteurs dans notre environnement peuvent affecter ce nombre. J'étudie si nous pouvons améliorer l'aspect d'envoi de courrier. –

Questions connexes