2010-04-26 27 views
8

Tengo un servicio .NET que procesa una cola en un hilo de fondo y de los elementos en la cola envía una gran cantidad de mensajes de correo electrónico pequeños a un nivel muy bajo. alta velocidad (digamos 100 mensajes por segundo si eso es posible). Actualmente, uso SmtpClient.Send() pero me temo que puede obstaculizar el rendimiento.Envío de correo electrónico SMTP a alta velocidad en .NET

Cada llamada a Send() pasa a través de un ciclo completo de apertura de la toma de corriente, la realización de la conversación SMTP (HELO, MAIL FROM, RCPT TO, DATA) y el cierre de la toma de corriente. En pseudocódigo:

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

(Editar:. Esta declaración acerca de SmtpClient.Send() de hecho es falsa como he explicado en mi respuesta)

Me gustaría pensar que el siguiente pseudo código sería más óptimo:

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

¿Debo estar preocupado por el rendimiento de SmtpClient.Send() al enviar correo electrónico a un ritmo elevado? ¿Cuáles son mis opciones para optimizar el rendimiento?

+0

¿estos mensajes son iguales, pero para diferentes destinatarios, o el contenido del correo electrónico es diferente? –

+0

@Rob Levine: Mismo destinatario, pero diferente contenido. –

+0

a cientos por segundo? ¿Quién en la tierra quiere ser enterrado bajo ese gran correo electrónico? –

Respuesta

7

La clase SmtpClient está almacenando en caché las conexiones del servidor SMTP detrás de escena. Llamar al SmtpClient.Send() repetidamente para enviar múltiples mensajes al mismo servidor SMTP ejecutará efectivamente el pseudo código en el segundo ejemplo.

Una forma de mejorar el rendimiento puede ser utilizar varias instancias de SmtpClient ejecutándose en varios subprocesos. En lugar de tener solo una conexión con el servidor SMTP, el servicio ahora tendrá muchas conexiones simultáneas. Los mensajes de correo electrónico entrantes se toman de la cola y se envían a un grupo de subprocesos de trabajo que llama al SmtpClient.Send() para enviar el mensaje al servidor SMTP.

He realizado algunas pruebas rudimentarias y he descubierto que esto puede mejorar el rendimiento hasta en un 100%. Sin embargo, la cantidad óptima de conexiones simultáneas y la mejora real del rendimiento probablemente dependan en gran medida del servidor SMTP. Una forma de ampliar esta idea es conectarse a múltiples servidores SMTP.

0

El proceso de envío de un correo electrónico utilizando SMTP se especifica (originalmente) en RFC 821. Ha habido numerosas actualizaciones y adiciones desde entonces, pero el protocolo básico sigue siendo el mismo. Debe comenzar cada transacción con un comando HELO y luego agregar la información del remitente, los destinatarios, etc. Si está enviando el mismo mensaje a todos los destinatarios, puede agregar múltiples destinatarios en un mensaje. Sin embargo, si el texto del mensaje es diferente para cada destinatario, creo que va a necesitar enviar mensajes individuales a cada uno, lo que significa una transacción por separado para cada uno.

+1

He descubierto que 'SmtpClient.Send()' cuando se le llama repetidamente solo abrirá el socket una vez, emitirá un comando EHLO y luego enviará múltiples comandos MAIL FROM, RCPT TO y DATA en la misma conexión. –

2

Cree un servidor de correo electrónico que envíe correos electrónicos de forma asincrónica utilizando un threadpool o algo así. De esa manera, puede "disparar y olvidar" sus correos electrónicos en el servidor y dejar que se preocupe por enviarlos a todos. Configúrelo con unos pocos hilos o más y debería poder enviar correos electrónicos bastante rápido.

+0

Eso es exactamente lo que estamos haciendo, excepto que parece que tenemos algunos problemas de rendimiento. Mi pregunta es sobre la forma más eficaz de "disparar y olvidar" los correos electrónicos de un servicio .NET. –

+0

¿Qué problemas de rendimiento? En mi implementación, podía enviar miles de correos electrónicos por minuto. ¿Está arrojando excepciones? Estos son increíblemente lentos en el correo, ya que a menudo tiene que esperar que se agote el tiempo de espera de un socket. – Chris

+0

En promedio, actualmente estamos enviando 20 correos electrónicos por segundo, pero hay muchos factores en nuestro entorno que pueden afectar este número. Estoy investigando si podemos mejorar el aspecto de envío de correo. –

Cuestiones relacionadas