搭建千万级别邮件发送平台
一. 前言
写邮件每个人都会,毕竟谁没有个QQ邮箱呢!调用邮件接口发邮件也是程序员的基本功,但是要一次发送一千万封邮件就不止是基本功了。大家可能经常听到『千万级别』这个量词,慢慢的会觉得千万级别的数据量不大,我们用钱来算就清晰了,发一千封邮件需要2块钱,一千万封就是2万块钱。你每天用QQ邮箱发送一千封邮件就等于挣了2块钱。我的任务是一天把2万块钱花出去。
如何快速的将数一千万封邮件发送出去?这个功能看上去和发送一千万条短信一样,找个靠谱的第三方推送平台,服务器上起多个进程,分分钟的事情。但是这个简单的功能我开发了三个多月。
虽然需求只有一句话『给注册用户发送推广邮件』(注册用户有一千多万)。但是凭借我多年写Bug的经验,产品经理肯定是想我搭建一个平台,一千万只是一个传进去的参数。这个平台就叫 EDM(Email Direct Marketing)吧,主要用于较大量的营销和推广类邮件发送。
二. 思考
接到『给注册用户发送推广邮件』的需求,我最初的想法如下:
-
因为发送邮件、短信、APP推送的业务非常相似,所以我打算做成一个消息中心,发邮件功能只是调用消息中心接口时传的一个名为Email的消息类型。
-
因为第三方邮件平台对接口调用频率肯定会有限制,所以我们需要计算申请多少个邮件服务帐号,起多少个发送进程。
-
因为邮件是按顺序发送(新用户先发,老用户后发),所以需要在进程间进行通信,可以使用信号量或者消息队列。
-
还有一些零散的优化点。比如要支持任务中断,支持用户已读/未读功能,邮件样式需要兼容Mac版Outlook客户端,右上角一定要有『在浏览器中查看此邮件』,右下角要有『取消订阅』。
依照如上规划,EDM平台很快就搭建完成,各个功能点测试一路畅通,于是正式上线投入生产。看着自己一气呵成写的项目完美上线,心情无比舒畅,不过这只是噩梦的开始……
按道理说不可能出问题,EDM项目中使用的每一个技术点都是我多次实践过的……当问题出现时我才发现EDM项目原来这么难,很多问题光凭技术还解决不了。成功投递一封邮件很简单,但是成功投递一千万封就难于上青天,技术只是解决问题的工具,当出现的问题没法用工具解决时,我们只能寻求理论支撑。
三. 理论支撑
我接触互联网时QQ这种IM工具就人人必备了,邮件对我来说是一种古老的沟通工具,除了工作中需要使用外,生活中都不会打开。Gmail中全是Facebook,Twitter,Linkedin的广告,QQ和网易邮箱更是惨不忍睹。这也导致我对Email协议一知片解。而首先要面对的就是各种『反垃圾邮件策略』导致的投递失败问题。
反垃圾邮件策略有很多,Email协议也定义了大量的规范,详情 http://www.faqs.org/rfcs/ 我将拿出主要的优化点来说明。
-
添加 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解析记录就行。
-
支持 DKIM、DMARC 协议
DKIM(DomainKeys Identified Mail)域名密钥识别邮件标准。发送方会在电子邮件的标头插入DKIM-Signature及电子签名信息。接收方则透过DNS查询得到公钥后进行验证。
DMARC(Domain-based Message Authentication, Reporting and Conformance)由Paypal,Google,微软,雅虎,ReturnPath等15家行业巨头(主要包括 金融机构,Email服务提供商,数据分析机构等)联手宣布成立了新的互联网联盟,致力于提交并推广一款[DMARC]新电子邮件安全协议。随着该联盟的日渐发展,继而有网易等其他行业先行者也加入到其中。
这两个协议特别不好加……需要你联系邮件服务商协助添加。
-
配置 List-Unsubscribe
List-Unsubscribe用来设置取消订阅参数,通常设置一个收件箱,比如 unsubscribe@test.com。主流的邮件服务器都会检测有没有该参数,有的话会直接在客户端显示一个『退订』的按钮(见下图)。比如Gmail中有时候就会显示,点击这个按钮就会自动往 unsubscribe@test.com 发送一封邮件,我们需要实时去检测 unsubscribe@test.com 邮箱中有没有收到用户发送的邮件,有的话下次就别再给该用户发邮件了,否则处罚严重。
如果你不设置这个参数很容易被邮件服务商拒收或者限制频率。List-Unsubscribe参数是设置在Email协议的请求头中,并不是在邮件内容中添加一个『取消订阅』的超链接。
-
调试技巧
可以到 http://www.mail-tester.com/ 去看邮件的得分情况,主要也是检测如上参数,生效与否一目了然。
Gmail中可以查看原始邮件的内容,https://mail.google.com/mail/u/0/#inbox
配置了如上所有参数之后,EDM平台发送的邮件测试得分基本在99分以上,皆大欢喜!
不过开心的太早了,通过配置各种协议和参数我们只能提高邮件的到达率,但是并不能保证邮件不被拒收。国内的邮件服务商巨头网易和腾讯并不是所有邮件都收,他们的策略如下:
-
每分钟,每小时,每天都有对应的发送量限制;
针对不同的厂商我们通过计划任务去执行不一样的发送频率,比如网易的每分钟只发15个,腾讯的每分钟只发20个,以此类推……但是有上千万封邮件要发送,肯定不能发几年。于是申请了多个发送邮箱来并发发送,好在这些发送逻辑都能通过代码实现,代码能解决的问题都不算问题。
-
邮件内容的质量把控
归根到底如果邮件内容的质量很低,技术优化的再好用户还是会扔到垃圾桶或者举报。举报的次数一多,邮件服务商给的额度就越低,比如一分钟只让发5封……1000万封得发送20年(当然真实情况不会这样,加入邮件服务商的联盟之后都好办)。
所以我们花了大量的工作在邮件内容的把控上,每一封发出去的邮件都需要多人审核,多端多平台样式测试。最后确保每一封邮件都很精致,让用户没那么反感。
四. 最后
现在EDM平台能保证邮件的到达率保持在97%以上,此处应该有掌声。一千万封邮件发送一次就是2万,如果不努力提高送达率就是把钱打水漂,这个功能也没有开发的意义。写代码时间越久就越发的觉得技术只是拿来服务用户的,如果代码产生不了价值其实就是垃圾代码。
最后奉劝各位推销人员。如果邮件样式丑陋或者明知是欺骗人的广告,真的别给用户发了,根本达不到你想要的曝光率和转化率,最后不但浪费钱还让人反感。
喜欢编程的朋友可以关注我的个人公众号,保证每周三篇原创。 程序员编程日志