Play + Mongo + AWS 實作電子報系統
第一篇就由花了兩天半時間的電子報系統開始吧, 上次產品的定期電子報發送是第一次嘗試 AWS SES, 使用 ruby with mailer 傳送電子報, 不過可能由於 smtp 的 overhead, 導致每發送一封 mail 約花上3~5秒的時間, 所以同時使用了超過20個 instance 發送, 最後因為沒有 handle 到某個 exception 所以只發了約 60K的使用者就中斷了。
這次決定嘗試重新寫一個完整且獨立的電子報發送系統, 初次 beta 必須具備以下功能:
透過 SES 發送電子報
有收件者歷史管理(包含退信、開信、狀態管理)
有電子報歷史管理
介紹一下用到的工具:
Play framework (ver. 2.2)
Mongo DB
AWS SES + SNS
最近密集的使用 Play! 開發多個新的 project, 主要是希望盡量的 follow MVC model 以及增加 productive, 最重要的是看中他的 NIO。 而選用 Mongo 沒有用 MySQL or Cassandra 甚至是其他 Data Storage 主因是 mongo 允許我快速開發且依然兼顧後續系統的擴充性, 當然他不是最好,卻是一時之選。 Amazon SES 用來發送 Email,好處是不需要自己維護 mail server , 更是仰賴 Amazon 的 low spam rating, 而 Amazon SNS 是用來接收 SES 的 Notification (包含 bounce, compliant)。
在資料庫規劃的部份,我捨棄了 mongo 提供的 reference 功能, 獨立存放且維護彼此的關聯,這樣希望可以保留後續要轉 column based 的彈性。
討論一下流程,系統管理員透過後台編輯好電子報後,透過 csv 整批發送, 系統會先將所有的收件者建檔並且建立到資料庫,然後 schedule 一個 Job 在稍後發送,這個 Job 會不斷清空這封電子報的 send queue,而我也放棄了 SES 的 multi-receipts 功能,Amazon 有一些限制,例如同一封信最高只能包含 50個 receipts,或是每秒只能發送多少封 mail ...等,即使使用 multi-receipts 可以大幅提昇發送速度,但是我希望做到 per user tracking,所以就放棄了,但是最令我意外的是,當我把超過 160K 的清單丟到後台後, 透過 SES API 傳送 Email 的速度卻只有 1.5 mails per second,這樣的速度要花超過一天半才能發送完所有的 user,之後可能有需要透過 thread 解決,但是這個 queue 的 maintain 又會是一個問題。
總之,這次的嘗試保留的後續的彈性, 且透過 Play! 開發也保留的 RoR 的特性卻又更 Robust, 算是一次還算成功的測試。










