做了四个月的邮件系统,准备修改为开源版本,收集意见中~ - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
vincenting
V2EX    程序员

做了四个月的邮件系统,准备修改为开源版本,收集意见中~

  •  8
     
  •   vincenting
    vincenting 2014-09-13 11:29:28 +08:00 15018 次点击
    这是一个创建于 4124 天前的主题,其中的信息可能已经有所发展或是发生改变。
    做这个项目的初衷很简单,很多人吐槽mailgun、sendcloud的独立IP价格略贵,同时mailgun不能有效的去兼容特别是QQ的发送规则,目前的产品形态参加 http://jianxin.io/ (应该会在下面的某天关闭),简单介绍下现在的设计以及准备修改并且开源的版本。

    当前功能(忽略各种用户体系):

    1. 自动生成 dkim 的记录值,并检测 dns 情况。
    2. 邮件分为普通邮件和紧急邮件,其中普通邮件为根据队列发送的邮件,紧急邮件为立刻发送的邮件。
    3. 发送中遇到错误,分析是否为用户不存在,否则暂停发送一段时间后继续发送。
    4. 支持 SMTP 协议以及 HTTP 协议的接口调用,并可选使用长连接直接返回邮件发送结果。

    目前想到的开源版的功能:

    1. 去除目前的用户体系,将域名添加变成域名和发送IP添加(可以使用自己的VPS进行发送,并且可以绑定反向域名解析)。
    2. 增加针对收件域(例如 QQ)的发件频率控制。
    3. 更丰富的日志。

    如果想了解邮件发送的原理,可以参考我之前写的帖子 : http://blog.segmentfault.com/vincent/1190000000661065

    当前的代码结构:

    1. 发送器(golang实现),postfix 或者 nodemail 同等级的服务。负责邮件任务的处理(邮件队列、邮件的投递、以及邮件返回错误的初步处理(判断是否为收件人不存在))。
    2. 服务分发(golang实现),目前主要负责和发送器间的通讯,以及发送器健康状况的检测。
    3. API 服务(Ruby的cramp实现),HTTP 调用方式的请求服务,包括发邮件、获取发送列表、当前用户状态等等的接口。
    4. 业务服务(Ruby的sinatra实现),就是你可以看到的网站自身。
    5. MTA(Nodejs实现),负责将SMTP协议的请求转发给 API 服务。

    思考了好久才决定转化为开源产品,如果有负责过邮件的前辈,希望分享下曾经遇到过的其他问题,大家一起来打造一款更好的开源邮件服务。
    第 1 条附言    2014-09-14 17:32:04 +08:00
    说下目前的计划:

    1. 正在开发(已经完成40%)一个小工具,类似 teambition 的公开版,告诉别人项目哪些正在开发、哪些即将开发、哪些完成了,预计 16 号完成。同时增加一个简单的新需求申请提交、投票、讨论功能。准备使用 MIT 协议开源。
    2. 开源验证码功能,预计耗时两天,整理下代码以及文档,使用 MIT 协议开源。
    3. 使用工具制定 jianxin 的开源开发计划(之前代码的重构以及部分模块的重写),预计耗时两个月,使用 GPL 协议开源。
    4. 后面的待定。
    73 条回复    2014-11-14 15:44:35 +08:00
    jaylong
        1
    jaylong  
       2014-09-13 11:49:48 +08:00
    Cool 很赞的页面
    Sukizen
        2
    Sukizen  
       2014-09-13 11:53:06 +08:00
    good! 赞一个
    shiny
        3
    shiny  
    PRO
       2014-09-13 12:03:21 +08:00   2
    http://jianxin.io/captcha?t=1410580975965
    Internal Server Error

    用了这么多语言,安装会不会很麻烦。
    kslr
        4
    kslr  
       2014-09-13 12:08:31 +08:00
    顶楼上,总共使用了3种语言,安装配置将是个麻烦。
    选好主要开发语言和框架统一开发,要不共享的代码也是乱七八糟的。
    kindlepaper
        5
    kindlepaper  
       2014-09-13 2:09:00 +08:00
    Daizong
        6
    Daizong  
       2014-09-13 12:09:02 +08:00
    Cool,期待开源
    hardywu
        7
    hardywu  
       2014-09-13 12:14:09 +08:00
    可以和iredmail 的作者聊聊。
    kmvan
        8
    kmvan  
       2014-09-13 12:14:38 +08:00
    回答下面的问题,那个图片显示不到啊~
    coolicer
        9
    coolicer  
       2014-09-13 12:22:46 +08:00
    期待开源++
    oott123
        10
    oott123  
       2014-09-13 12:25:15 +08:00 via Android
    很漂亮~
    不过技术栈真是…好多…
    dbbbit
        11
    dbbbit  
       2014-09-13 12:26:44 +08:00
    @vincenting 如何解决发送量大被 block 的问题(正常邮件)?
    guotie
        12
    guotie  
       2014-09-13 12:32:15 +08:00
    赞!
    vincenting
        13
    vincenting  
    OP
       2014-09-13 12:54:08 +08:00
    @kmvan 已经修复,验证码服务莫名挂掉,没有做守护进程。。
    vincenting
        14
    vincenting  
    OP
       2014-09-13 12:55:58 +08:00
    @shiny 这个是个问题,下面研究研究怎么通过 shell 脚本一键安装~
    vincenting
        15
    vincenting  
    OP
       2014-09-13 12:57:46 +08:00
    @dbbbit 这个在QQ邮箱比较常见,参见 http://weibo.com/p/1001603727504811684569http://park.jobdeer.com/discussion/19/%E9%82%AE%E4%BB%B6%E5%8F%91%E9%80%81%E9%82%A3%E7%82%B9%E4%BA%8B 。建议是使用 nodejs 的 mailin 这样的服务进行收件,对 block 邮件进行处理,并且使用 QQ 的开发服务,可以试试接受反馈。通过反馈调整发送频率(我开源版里面准备增加的)。我目前的想法。
    vincenting
        16
    vincenting  
    OP
       2014-09-13 12:58:41 +08:00
    @dbbbit 改正=》QQ的开放服务 http://open.mail.qq.com/
    vincenting
        17
    vincenting  
    OP
       2014-09-13 13:00:03 +08:00
    @kslr 存在这个问题,而且主要是 ruby 和 nodejs(服务还用到了 mongo),golang可以通过使用对应系统下的可执行文件来解决部署问题。
    nilai
        18
    nilai  
       2014-09-13 13:11:54 +08:00
    首先, 期待开源。
    其次, 支持楼主精神。
    最后, 支持
    startover
        19
    startover  
       2014-09-13 13:19:29 +08:00
    很nice的设计~~赞一个!!
    longquanwo
        20
    longquanwo  
       2014-09-13 13:37:10 +08:00   1
    发表一下个人看法:定位微型企业,提供定制化、内容化邮件服务。qq企业邮箱已经开始想收费模式转移,这玩意迟早要全部变成收费模式。
    nilai
        21
    nilai  
       2014-09-13 13:40:02 +08:00
    楼主什么时候开源呢? 期待呢
    qiuai
        22
    qiuai  
    PRO
       2014-09-13 14:05:15 +08:00
    如果安装方便的话,我要用.
    mengzhuo
        23
    mengzhuo  
       2014-09-13 14:13:54 +08:00   1
    发送的话,还差SPF DMARC报告收信

    SMTP需要STARTTLS加密
    API也需要SSL加密
    dbbbit
        24
    dbbbit  
       2014-09-13 14:35:03 +08:00   1
    @vincenting
    其实也没必要针对qq做太多的调整,能控制频率,控制量就行了。
    说到底,能发多少还是要看自己在qq那儿的额度。
    我之前优化过的邮件服务器,一天对qq能发七到八万,但还是不够。
    用户中qq邮件用户占了绝大多数。

    不知到你们对日志的是否做统计处理?
    个人觉得统计对于了解发送情况并调整发送策略非常有用。
    liteneo
        25
    liteneo  
       2014-09-13 14:36:19 +08:00
    非常赞
    qiuai
        26
    qiuai  
    PRO
       2014-09-13 14:40:47 +08:00
    @vincenting 我试用了现在的简信,很喜欢的模式.
    但是在测试发送时,执行提示 {"code":405,"msg":"Secret expired."} 代码是从 php Version里直接复制出来的.什么地方错了呢?
    vincenting
        27
    vincenting  
    OP
       2014-09-13 15:10:24 +08:00
    @dbbbit 统计就是主要就是想结合 QQ 邮箱自身的服务,包括 “他域互通管理” http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20006&&no=1000938 以及 “垃圾邮件举报反馈系统” 系统来进行调整。

    系统这里可以来进行发送频率控制,遇到发送错误,如果鉴定为非用户不存在(自己整理了一个关键字列表)的情况,然后有一个相应的尝试机制。

    恩,很赞成统计(反馈)的重要性~
    vincenting
        28
    vincenting  
    OP
       2014-09-13 15:11:36 +08:00
    @nilai 先整理下开源版的设计,然后在现有系统的基础上进行修改。
    代码随着新版的开发同步开放出来。
    lazyphp
        29
    lazyphp  
       2014-09-13 15:22:43 +08:00
    很不错啊!支持楼主开源。
    Yien
        30
    Yien  
       2014-09-13 15:26:15 +08:00
    期待
    blueandhack
        31
    blueandhack  
       2014-09-13 15:28:01 +08:00
    支持开源
    哈~爱滴滴~非科班出生,现在挺牛的啊~
    dbbbit
        32
    dbbbit  
       2014-09-13 15:31:14 +08:00
    @vincenting
    虽然qq邮箱用户可能占到大多数,但是最好避免过分重视qq邮箱。
    结合 QQ 邮箱自身的服务固然不错,但只是加分项。
    其他邮件服务比如 163等的额度往往比qq 还要低很多(虽然相应的用户不多)
    日志统计其实已经能够获得除用户举报等信息外的全部信息,打开率也应该有自己的统计方法。
    更一般的做法就是从日志来获取反馈,postfix 或者 nodemail应该都有详细的日志和统计插件可用。(避免很多不必要的开发)

    发送错误的情况,如果邮件量比较大(出错占的比例较小),视邮件重要性有可配置的尝试次数。
    因为尝试会消耗你的发信额度,一般宣传邮件失败可直接丢弃。
    humiaozuzu
        33
    humiaozuzu  
       2014-09-13 15:31:32 +08:00
    请教下验证码服务是如何实现的?
    gangsta
        34
    gangsta  
       2014-09-13 15:40:52 +08:00
    页面设计很赞!
    lhbc
        35
    lhbc  
       2014-09-13 15:51:26 +08:00 via iPhone
    支持RADIUS/LDAP验证吗?还有两步验证,SMTP/POP/IMAP等服务支持专用密码,类似gmail的应用密码。
    hustlzp
        36
    hustlzp  
       2014-09-13 17:02:29 +08:00
    LZ太强悍了,前后端、设计什么的都自己做,而且做的都很赞!
    atie
        37
    atie  
       2014-09-13 17:17:52 +08:00
    界面真得不错!
    vincenting
        38
    vincenting  
    OP
       2014-09-13 17:36:08 +08:00
    @humiaozuzu 图片生成使用imagemagick,大概思路:
    1. 随机出题目(随机符号,然后随机第一个数字、随机第二个数字)
    2. 随机将部分数字变成文字
    3. 随机字体和颜色

    由于代码企业也在用,所以就不方便开源了
    vincenting
        39
    vincenting  
    OP
       2014-09-13 17:37:02 +08:00
    @blueandhack 哈哈,掐指一算三年多了。
    vincenting
        40
    vincenting  
    OP
       2014-09-13 17:54:34 +08:00
    @lhbc 恩,MTA模块就是提供Gmail的STMP使用账号发送的功能,只是网站上没有体现出来~
    ichou
        41
    ichou  
       2014-09-13 18:17:06 +08:00
    @qiuai 正在调试问题 不过我无法再现你的错误
    方便给我邮件吗? me(at)ichou.cn 麻烦您了
    coosir
        42
    coosir  
       2014-09-13 18:31:18 +08:00
    很赞,前端也很厉害哦,一直很期望这方面有比较好的开源系统。
    lfzyx
        43
    lfzyx  
       2014-09-13 18:40:40 +08:00
    话说ls诸位都不关心lz用哪种开源协议吗?
    qiuai
        44
    qiuai  
    PRO
       2014-09-13 18:58:02 +08:00
    @ichou 已经发送邮件,我无法在服务器上ping通api.jianxin.io,没有禁用任何函数.
    vincenting
        45
    vincenting  
    OP
       2014-09-13 19:04:50 +08:00
    @qiuai 因为我禁 ping 了,尝试 curl 'http://api.jianxin.io'
    vincenting
        46
    vincenting  
    OP
       2014-09-13 19:05:29 +08:00
    @lfzyx 目前考虑采用 GPL 协议进行开源。
    raincious
        47
    raincious  
       2014-09-13 19:10:17 +08:00
    @vincenting 好严格呢。为什么不用MIT?
    vincenting
        48
    vincenting  
    OP
       2014-09-13 19:17:01 +08:00   1
    @dbbbit 恩,我考虑的是单从发送组件说的话,只提供发送频率修改这样的一个功能。还有就是详细的发送结果日志(通过SMTP协议通信后,对方服务最终给出的是否投递成功的日志)。QQ 的的确只是加分项,让用户更好的把握投递频率。

    邮件打开率/邮件链接打开率我的理解是通过在邮件内嵌入空白图片标签进行邮件阅读统计,加上类似短域名的类似的服务进行链接打开率统计。这个可以使用开源方案解决。

    发送错误处理,我考虑的还是分为两种:
    1. 普通广播形式的邮件(例如订阅的文章),这种不需要当日送达。虽然重复投递(间隔很久,会放到队列的最后)可能浪费当日的限额,但是后面的邮件可以依次推迟,放到后面。
    2. 紧急并且需要实时投递的邮件,我有设计一个长连接式的接口,直接会返回发送情况,如果投递失败的话,用户可以在多台机器间(或者后期添加发送组的概念,直接程序集成)切换进行直到发送成功,毕竟目前主要还是对IP进行限制。
    qiuai
        49
    qiuai  
    PRO
       2014-09-13 19:20:34 +08:00
    @vincenting
    # curl 'http://api.jianxin.io'
    Your request couldn't be found
    vincenting
        50
    vincenting  
    OP
       2014-09-13 19:27:07 +08:00
    @qiuai 恩啊,这个没有问题的。PHP所有版本的代码是 @ichou 提供的,尝试修改下代码,将 'expire' => time() + 10 里面的 10 换成更大的值看看。
    qiuai
        51
    qiuai  
    PRO
       2014-09-13 19:27:58 +08:00
    @vincenting 切换成100后 {"code":200,"id":"54142a2bc2a7**************","msg":"in queue"}
    qiuai
        52
    qiuai  
    PRO
       2014-09-13 19:30:39 +08:00
    @vincenting 什么时候推收费服务?一天30封我目前倒是够用的...但是如果你不知道啥时候就把服务停了...
    vincenting
        53
    vincenting  
    OP
       2014-09-13 19:35:39 +08:00
    @qiuai 小量邮件建议接入 mailgun(项目很大程度借鉴了 mailgun 的设计)。这个服务很快就要停止维护转而专心准备开源版的项目。

    到时候可以关注下开源版,可以在自己 VPS/服务器 上搭建个人版的邮件服务器。
    qiuai
        54
    qiuai  
    PRO
       2014-09-13 19:37:12 +08:00
    @vincenting 好吧...期待开源版本.至少要能完成现在的效果...
    vincenting
        55
    vincenting  
    OP
       2014-09-13 20:00:09 +08:00   1
    @raincious

    1. 开源是因为我希望对于开发者来说可以有一个更好的邮件发送服务的选择(够用并且好用)
    2. 使用 GPL 是因为最终开源的我也会尽力做成产品基本的代码,而不是功能/模块级别的
    3. 同时我自己也保留后期商业运作(提供云端邮件系统,让简信复活)这样的可能性(还是有点私心)
    dbbbit
        56
    dbbbit  
       2014-09-13 20:08:07 +08:00
    @vincenting
    测试方面,是否有比较好的解决方案?
    vincenting
        57
    vincenting  
    OP
       2014-09-13 20:17:19 +08:00
    @dbbbit 测试指的是调整策略来观察投递的效果么?这个的话目前没有,目前都是依赖之前一次大规模投送的经验还有看别人的总结来制定我的规则。实际投递的话风险太大。

    如果是开发时候的测试,我是在测试的时候将实际投递的代码换成了模拟投递,随机返回错误。
    gentleming
        58
    gentleming  
       2014-09-13 20:29:11 +08:00
    前端很赞,顶一个。
    期待将来有机会能使用。
    iwinux
        59
    iwinux  
       2014-09-14 09:04:54 +08:00   1
    看了一眼 UI 就觉得应该会很赞 XD

    关于应用的部署和分发,如果依赖较多的话(比如需要 Ruby + Node.js),可以试试用 https://github.com/opscode/omnibus 将应用打包成 all-in-one 的安装包(支持 deb / rpm)~

    期待项目的开源
    TrickLin
        60
    TrickLin  
       2014-09-14 09:12:46 +08:00 via Android
    支持,太赞
    roymax
        61
    roymax  
       2014-09-14 12:22:35 +08:00
    @vincenting 对验证码感兴趣,要不先把这个开源
    vincenting
        62
    vincenting  
    OP
       2014-09-14 13:36:35 +08:00
    @roymax 考虑下,不过这个部署可能会略麻烦,用到了 imagemagic 和 golang。
    jecky15
        63
    jecky15  
       2014-09-14 13:54:37 +08:00
    可以参考哈mailerq的 ,用消息列队处理邮件。
    jecky15
        64
    jecky15  
       2014-09-14 13:56:44 +08:00   1
    @vincenting可以参考哈mailerq的 ,用消息列队处理邮件。
    vincenting
        65
    vincenting  
    OP
       2014-09-14 14:04:35 +08:00   1
    @jecky15 恩,好好研究下~
    jecky15
        66
    jecky15  
       2014-09-14 14:21:00 +08:00
    @vincenting 虽然我没有看懂你想做什么?想做一个类似mailgun这种带服务带接口的服务商,还是只需要要一个cp,可以在cp里面设置N多家的key等,来实现邮件发送以及统计等(邮件营销方面)。
    vincenting
        67
    vincenting  
    OP
       2014-09-14 14:25:42 +08:00
    @jecky15 现在的话,是准备做一个功能(特别是调用方式)于 mailgun 类似,可以在自己服务器上部署的邮件服务器,前期核心只有一个发件(强制绑定 SPF DKIM,并且自带队列控制投递频率,以及一些错误处理回调等等)。
    其他的统计等等在后期自己实现/集成其他开源服务。
    jecky15
        68
    jecky15  
       2014-09-14 14:41:27 +08:00
    @vincenting ok,明白了,谢谢
    openroc
        69
    openroc  
       2014-09-14 15:15:43 +08:00
    gogo
    foursking
        70
    foursking  
       2014-09-14 16:34:39 +08:00
    star一下
    nilai
        71
    nilai  
       2014-09-15 19:10:15 +08:00
    支持,期待.楼主加油.
    woyao
        72
    woyao  
       2014-11-14 12:02:22 +08:00
    @vincenting 打不开了,项目已停?
    vincenting
        73
    vincenting  
    OP
       2014-11-14 15:44:35 +08:00
    @woyao yes,开源版多数已经放出来了,不过现在还在想下面怎么弄。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5655 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 43ms UTC 02:38 PVG 10:38 LAX 18:38 JFK 21:38
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86