2010-04-26 25 views
8

我有一個.NET服務處理後臺線程上的隊列,並且從隊列中的項目發出大量小型電子郵件高速率(例如,如果甚至可能,則爲每秒100條消息)。目前,我使用SmtpClient.Send(),但恐怕會妨礙性能。在.NET中以高費率發送SMTP電子郵件

每次調用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()的表現?我有什麼選擇來優化性能?

+0

這幾條信息幾乎一樣,但對不同的收件人,或者是電子郵件的內容不同? – 2010-04-26 13:36:26

+0

@Rob Levine:收件人相同,但內容不同。 – 2010-04-26 13:45:02

+0

幾百秒?誰在地球上想要被埋在那麼多電子郵件之下? – 2010-04-26 13:52:34

回答

7

SmtpClient類在後臺高速緩存SMTP服務器連接。反覆調用SmtpClient.Send()將多條消息提交給同一個SMTP服務器將有效地執行第二個示例中的僞代碼。

提高性能的一種方法可能是使用在多個線程上運行的多個實例SmtpClient。現在,服務只有一個到SMTP服務器的連接,而現在有許多併發連接。從隊列中取出電子郵件消息,並將其分派到一個工作線程池中,該線程調用SmtpClient.Send()將消息發送到SMTP服務器。

我已經做了一些基本的測試,發現這可能會提高多達100%的性能。但是,併發連接的最佳數量和實際的性能改進可能非常依賴於SMTP服務器。擴展這個想法的一種方法是連接到多個SMTP服務器。

0

RFC 821中指定(最初)使用SMTP發送電子郵件的過程。自那以後有很多更新和補充,但基本協議仍然相同。您需要使用HELO命令啓動每個事務,然後添加發件人信息,收件人等。如果您將同一郵件發送給所有收件人,則可以在一條郵件中添加多個收件人。但是,如果郵件的文本對於每個收件人都不同,我認爲您需要將單個郵件發送給每個郵件,這意味着每個郵件都有單獨的交易。

+1

重複調用時,我發現'SmtpClient.Send()'只會打開一次套接字,發出一個EHLO命令,然後在同一個連接上提交多個MAIL FROM,RCPT TO和DATA命令。 – 2010-04-27 14:50:27

2

創建一個電子郵件服務器,使用線程池或其他東西異步發送電子郵件。這樣,您就可以在服務器上「發送並忘記」您的電子郵件,並讓它擔心將它們全部發送出去。設置一些線程或更多,它應該能夠通過電子郵件快速鞭打。

+0

這正是我們正在做的,除了我們似乎有一些性能問題。我的問題是關於從.NET服務「發射並忘記」電子郵件的最高性能方法。 – 2010-04-26 13:53:36

+0

什麼表現問題?在我的實施中,我可以每分鐘發送數千封電子郵件。它拋出異常嗎?這些郵件的速度非常慢,因爲您經常需要等待套接字超時。 – Chris 2010-04-26 14:26:14

+0

目前我們平均每秒發送20封電子郵件,但在我們的環境中有很多因素會影響這個數字。我正在調查是否可以改進郵件發送方面。 – 2010-04-26 14:40:05