搭建百萬級別郵件傳送平臺

sibenx發表於2017-06-27

一. 前言

呼叫郵件介面傳送郵件是再簡單不過的功能。但是要做成平臺並且支援百萬級別的傳送量,就沒那麼簡單。

如何快速的將數百萬封郵件推送出去?這個功能看上去和傳送數百萬條簡訊一樣。找個靠譜的第三方推送平臺,起多個程式,分分鐘的事情,瓶頸肯定是在第三方平臺而不是我們這裡。但是這個簡單的百萬級別郵件傳送平臺(EDM)耗費了我3個多月的時間。

EDM(Email Direct Marketing)主要用於較大量的營銷和推廣類郵件傳送。我搭建的EDM平臺主要用於給訂閱使用者傳送推廣類郵件和通知類郵件。

二. 思考

最初我們的需求是需要定期給100W使用者推送郵件,接到這個需求時我最初的想法如下:

  1. 因為傳送郵件、簡訊、APP推送的業務非常相似,所以我打算做成一個訊息中心,發郵件功能只是呼叫訊息中心介面時傳的一個名為email的訊息型別。
  2. 因為第三方郵件平臺對介面呼叫頻率肯定會有限制,所以我們需要計算申請多少個發件郵箱,起多少個傳送程式。
  3. 因為郵件是按順序傳送(新使用者先發,老使用者後發),所以需要在程式間進行通訊,使用訊號量或者訊息佇列。
  4. 還有一些零散的優化點。比如要支援任務中斷,支援使用者已讀功能,郵件樣式需要相容Mac版Outlook客戶端,右上角一定要有『在瀏覽器中檢視此郵件』,右下角要有『取消訂閱』。

依照如上規劃,EDM平臺很快就搭建完成,各個功能點測試一路暢通,於是正式上線投入生產。看著自己一氣呵成寫的專案完美上線,心情無比舒暢,不過這只是噩夢的開始……

按道理說不可能出問題,EDM專案中使用的每一個技術點都是我拿手的方案……當問題出現時我才發現EDM專案原來這麼難,很多問題不是技術能解決的。成功投遞一封郵件很簡單,但是成功投遞100W封就難於上青天,技術只是解決問題的工具,當出現的問題沒法用工具解決時,我們只能尋求理論支撐。

三. 我要的理論支撐

我接觸網際網路時QQ這種IM工具就人人必備了,郵件對我來說是一種古老的溝通工具,除了工作中需要使用外,生活中都不會開啟。Gmail中全是Facebook,Twitter,Linkedin的廣告,QQ和網易郵箱更是慘不忍睹。這也導致我對Email協議的瞭解少的可憐。而我首先要面對的就是各種『反垃圾郵件策略』導致的投遞失敗問題。

反垃圾郵件策略有很多,Email協議也定義了大量的規範,詳情 http://www.faqs.org/rfcs/ 我將拿出主要的優化點來說明。

  1. 新增 MX 與 SPF 記錄

    
    MX(Mail Exchanger)是郵件交換記錄,它指向一個郵件伺服器,用於電子郵件系統發郵件時根據收信人的地址字尾來定位郵件伺服器。使用者可以將該域名下的郵件伺服器指向到自己的mail server上,然後可自行操控所有的郵箱設定。
    
    SPF (Sender Policy Framework)發信者策略架構,通常都直接稱為SPF,SPF是為了防範垃圾郵件而提出來的一種DNS記錄型別,它是一種TXT型別的記錄,它用於登記某個域名擁有的用來外發郵件的所有IP地址。
    
    SPF是跟DNS相關的一項技術,它的內容寫在DNS的txt型別的記錄裡面。MX記錄的作用是給寄信者指明某個域名的郵件伺服器有哪些。SPF的作用跟MX相反,它向收信者表明,哪些郵件伺服器是經過某個域名認可會傳送郵件的。
    
    SPF的作用主要是反垃圾郵件,主要針對那些發信人偽造域名的垃圾郵件。
    
    這兩個引數很好加,新增兩條DNS解析記錄就行。
    
  2. 支援 DKIM、DMARC 協議

    DKIM(DomainKeys Identified Mail)域名金鑰識別郵件標準。傳送方會在電子郵件的標頭插入DKIM-Signature及電子簽名資訊。接收方則透過DNS查詢得到公鑰後進行驗證。
    
    DMARC(Domain-based Message Authentication, Reporting and Conformance)由Paypal,Google,微軟,雅虎,ReturnPath等15家行業巨頭(主要包括 金融機構,Email服務提供商,資料分析機構等)聯手宣佈成立了新的網際網路聯盟,致力於提交併推廣一款[DMARC]新電子郵件安全協議。隨著該聯盟的日漸發展,繼而有網易等其他行業先行者也加入到其中。
    
    這兩個協議特別不好加……如果你使用的是阿里雲郵箱服務,可以聯絡客服幫忙新增。
    
  3. 配置 List-Unsubscribe

    List-Unsubscribe用來設定取消訂閱引數,通常設定一個收件箱,比如 unsubscribe@test.com。主流的郵件伺服器都會檢測有沒有該引數,有的話會直接在客戶端顯示一個『取消訂閱』的按鈕。比如Gmail中有時候就會顯示,點選這個按鈕就會自動往 unsubscribe@test.com 傳送一封郵件,我們需要實時去檢測 unsubscribe@test.com 郵箱中有沒有收到使用者傳送的郵件,有的話下次就別再給該使用者發郵件了,否則處罰嚴重。
    
    如果你不設定這個引數很容易被郵件服務商拒收或者限制頻率。List-Unsubscribe引數是設定在Email協議的請求頭中,並不是在郵件內容中新增一個『取消訂閱』的超連結。
    
  4. 除錯技巧

    可以到 [http://www.mail-tester.com/](http://www.mail-tester.com/) 去看郵件的得分情況,主要就是檢測如上引數,生效與否一目瞭然。
    
    Gmail中可以檢視原始郵件的內容,[https://mail.google.com/mail/u/0/#inbox](https://mail.google.com/mail/u/0/#inbox) 
    

配置瞭如上所有引數之後,我們平臺傳送的郵件到測試平臺測試得分基本在99分以上,皆大歡喜!不過開心的太早了,通過配置各種協議和引數我們只能提高郵件的到達率,但是並不能保證郵件不被拒收。國內的郵件服務商網易和騰訊屬於郵箱巨頭,這兩巨頭並不是所有郵件都收,他們的策略如下:

  1. 每分鐘,每小時,每天都有對應的傳送量限制;

    針對不同的廠商我們通過計劃任務去執行不一樣的傳送頻率,比如網易的每分鐘只發15個,騰訊的每分鐘只發20個,以此類推……但是我們有上百萬封郵件要傳送,肯定不能發幾個月。於是申請了多個郵箱來同時傳送,這些傳送邏輯都能通過程式碼實現,程式碼能解決的問題都不算問題。
    
  2. 郵件內容的質量把控

    歸根到底如果郵件內容的質量很低,技術優化的再好使用者還是會扔到垃圾桶或者舉報。舉報的次數一多,郵件服務商給的額度就越低,比如一分鐘只讓發5封……100萬封得傳送2年(當然真實情況不會這樣,加入郵件服務商的聯盟之後都好辦)。
    
    所以我們花了大量的工作在郵件內容的把控上,每一封發出去的郵件都需要多人稽核,多端多平臺樣式測試。最後確保每一封郵件都很精緻,讓使用者有慾望開啟。當然作為程式設計師,很多我很反感和覺得不適合的內容最後還是會傳送到使用者手中,這點技術沒辦法優化。
    

四. 最後

現在EDM平臺能保證郵件的到達率保持在96%以上,百萬級別的郵件傳送一次就是幾千塊錢的費用,如果不努力提高送達率就是把錢打水漂,做這個功能也沒有存在的意義。寫程式碼時間越久就越發的覺得技術只是拿來服務使用者的,如果程式碼產生不了價值其實就是垃圾程式碼。

我的部落格:搭建百萬級別郵件傳送平臺


相關文章