我已經在Windows服務(C#)中編寫了一個組件,它負責發送大量的電子郵件。這些電子郵件將轉到許多域名上的收件人,其中包括真正的任何域名。 (是的,收件人需要電子郵件,不,我不是垃圾郵件。是的,我在與CAN-SPAM抱怨。是的,我知道sending email from code sucks。)許多電子郵件是事務性的到用戶操作);有些是批量(郵件合併基本上)。測試大批量SMTP電子郵件發送代碼的最佳方法是什麼?
我不想依賴外部SMTP服務器。 (其他考慮因素中,想要檢查郵箱中的退回郵件並嘗試解析郵件讓我感覺不好)。
我的設計非常簡單。事務消息和批量消息都會生成並插入到數據庫表中。此表格包含電子郵件信封和內容,以及嘗試計數和重試後的日期。
該服務運行一些工作線程,每次抓取20行並循環遍歷每個線程。使用Simple DNS Plus庫,我抓取收件人域的MX記錄,然後使用System.Net.Mail.SmtpClient
同步發送電子郵件。如果撥打Send()
成功,我可以將電子郵件出列。如果暫時失敗,我可以增加嘗試次數並設置適當的重試日期。如果它永久失敗,我可以出列並處理失敗。
顯然,將數千封測試郵件發送到數百個不同的實際域名是一個非常糟糕的想法。但是,我絕對需要對我的多線程發送代碼進行壓力測試。我也不太確定模擬SMTP的各種故障模式的最佳方式。另外,我想確保我能夠通過各種垃圾郵件控制方法(重名列出與網絡層最相關的東西)。
即使我最近發現我的ISP阻止連接到端口25的任意服務器,而不是我的ISP的SMTP服務器,我的小規模測試困難也加劇了。 (在生產中,這個東西當然會放在一個沒有阻塞端口25的服務器上,這並不能幫助我測試我的開發機器。)
所以,我最感興趣的兩件事情是:
- 我該如何去測試我的代碼?
SmtpClient.Send()
可能會失敗的各種方法是什麼?列出了六個例外;SmtpException
和SmtpFailedRecipientsException
似乎是最相關的。
更新:Marc B's answer指出,基本上,我創造我自己的SMTP服務器。他使我正在重新發明輪子的有效點,所以這裏是我的理由不使用「實際」一個(後綴,等等),而不是:
電子郵件有不同的發送優先級(雖然這是無關信封的
X-Priority
)。大量電子郵件是低優先級;事務性很高。 (並且任何電子郵件或一組電子郵件可進一步配置爲具有任意優先級。)我需要能夠暫停發送較低優先級的電子郵件,以便可以首先發送較高優先級的電子郵件。 (爲了達到這個目的,工作者線程每次獲得20個優先級隊列時,只需從隊列中選取最高優先級的項目。)如果我已經向外部SMTP服務器提交了幾千個大容量項目,那麼我現在無法將這些項目暫時擱置,而我現在要提交的項目已經發送。粗略的Google search顯示Postfix並不真正支持優先級; Sendmail優先考慮信封中的信息,這不符合我的需求。
我需要能夠向我的用戶顯示爆炸(一組批量電子郵件)的發送過程的進度。如果我只是把我所有的電子郵件都交給外部服務器,我不知道它在實際交付中有多遠。
因爲每個MTA的反彈信息都不同,所以我對解析反彈消息猶豫不決。 Sendmail的不同於Exchange的不同於
[...]
。另外,我會以什麼頻率檢查我的退回收件箱?如果退回消息本身未送達,該怎麼辦?我並不太擔心爆炸中途中斷。
如果我們在談論災難性故障(終止未處理的異常,斷電,無論什麼):由於工作線程在成功發送數據庫時從數據庫中取出每封郵件,我可以知道誰收到了爆炸,沒有。此外,當服務在失敗後重置時,它只會在隊列中停止的地方進行拾取。
如果我們正在談論本地故障(一個
SmtpException
,DNS故障等):我只記錄失敗,增加電子郵件的嘗試計數器,然後再試。 (這基本上是SMTP規範要求的。)在嘗試和之後,我可以永久性地使郵件失效(將郵件出列),並在稍後記錄失敗以供檢查。這樣,即使我的代碼第一次不是100%完美,我也可以發現奇怪的邊緣情況,即我的代碼無法處理–。 (老實說,這不會是)我希望roll-my-own路由最終可以讓我比使用外部SMTP服務器更快地發送郵件。如果服務器不在我的控制範圍內,我不得不擔心限速問題;即使它是,它仍然是一個瓶頸。我使用的多線程體系結構意味着我要並行連接到多個遠程服務器,從而減少傳遞消息所需的總時間。
我確實承擔了這種理解,實際上我確實創建了自己的SMTP服務器。我選擇了我自己的路線,原因是我添加到我的問題中。關於你答案的第二段:你能否擴展實際上做這些事情的方法? – josh3736 2010-07-26 08:05:28
灰名單很容易。有各種大型SMTP服務器的插件可以做到這一點。硬反彈只是「在這個地址沒有這樣的用戶」類型的錯誤。在防火牆上可以模擬ICMP問題,在Linux中使用iptables尤其容易。 – 2010-07-26 15:32:10