配置所有转发到php脚本的唯一每用户电子邮件地址的正确方法是什么?

Dav*_*ave 3 php email sendmail

我有一个大约的网络应用程序.30k用户并且增长迅速.我们希望通过电子邮件启用某些功能,这意味着为每个用户分配一个唯一的电子邮件地址(出于安全原因).发送到这些唯一地址的电子邮件应转发到PHP脚本.PHP脚本需要访问电子邮件的所有部分 - 标题,正文和任何附件.我不确定以什么方式设置它.我们目前正在使用sendmail,并且更愿意坚持使用(这是Linux,如果重要的话).我已经能够获得一个单独的电子邮件转发到脚本,但它不可扩展(在我看来)创建30k别名,然后每次新用户注册时创建一个新别名.我会更乐意使用某种类型的基于catch-all/RegEx的解决方案,它只是告诉PHP脚本作为收件人的唯一电子邮件地址,这将让我们查找用户.

Mar*_*ski 7

30k帐户不会向我们提供有关您希望处理的流量的任何信息.但我们假设这是另一个问题.

您可以创建catch all帐户类型,只需接受您创建用户地址的域中的任何电子邮件(基本上*@domain).然后你可以在每个传入邮件上启动你的处理脚本(你通常可以从stdin流中获取整个邮件正文(在PHP中可访问php://stdin),并根据你的喜好进行处理.但如果你想使用PHP(或者几乎所有脚本语言),因为每个邮件都需要生成新的PHP进程,初始化所有扩展等等.这一切都需要时间和资源,一个更大的垃圾邮件泛滥,你的盒子几乎被烤了.

或者,您可以像在任何其他邮件中一样在邮箱中收集邮件,然后让您的脚本从那里获取邮件(直接,挖掘maildir或通过IMAP或POP等邮件协议).从管理角度来看,这看起来更好,只要您的邮件服务器可以接受传入的邮件,您的整个系统仍然有效.您甚至可以通过设置一些过滤规则(在MTA级别上)来尝试对系统进行"分区",并将传入的邮件传递给单个邮箱,而不是更多.然后你可以并行处理这些邮件,而不用麻烦(不需要为处理多个实例的同一邮件而烦恼)."分区"模式可以是任何东西,即取决于您的完整地址命名方案,如果基于字母的单独邮箱a*@,b*@[a-d]*@](取决于流量),并不重要.

或者,您可以尝试将传入邮件的主体放入数据库,然后如上所述进行处理,而无需任何POP/IMAP处理.

无论您选择什么,我建议您不要将任何表格的处理脚本直接放在邮件接收流程链中.延迟1分钟通常不是问题(所以你可以运行任何类型的守护进程并获取处理邮件,cronjob等),用户可以等待那么多w/o抱怨 - 看起来即时处理很可能不是在你的情况下也是强制性的.但如果是,那么PHP 可能不是我担心的最佳工具选择.

编辑:(回答评论问题,而不是评论评论大小限制)

我不熟悉Sendmail足以在这里给你精确的配置指令(我在定制的qmail上),但我希望有一些一般性的提示.首先,我相信Sendmail支持虚拟用户(这意味着不存在用户的邮箱/etc/passwd).如果是这样,那么MTA通常应该让您查询数据库(以查明目标电子邮件地址是否有效以及该用户的主目录在哪里放入邮件)与一些内置提供程序.或者(甚至更好)调用外部程序来做到这一点.后者在这里是一个赢家,因为没有用户真的,所以你可以编写小脚本或(再次,更好的性能)C应用程序,可以做到这一点.因为您需要的是根据一些简单的预定义规则将传入的邮件"分离"到几个物理邮箱中,所以您可以完成几个if()s + substr()s.几行,没有DB需要,非常快.或者,甚至更好,你甚至可以roundrobin在这里尝试最愚蠢的方法 - 事实上,如果邮件点击accountAaccountB只有50%的邮件结束A而其他50%B(或者如果你去4个目标帐户则为25%)则无关紧要等等,这是你认为应该关心的唯一条件.你可以尝试使用procmail它,但我认为这是毫无意义的,并不是最好的性能.

至于将邮件放入数据库.这取决于MTA - 默认情况下没有人这么做,因为它比将邮件放入maildirs要慢(因为DB通常是其他主机),但仍然有几个解决方案.要么为Sendmail寻找第三方补丁,要么添加另一个将邮件从物理邮箱"复制"到DB中的脚本/应用程序.你可能会说 - 但它会慢一些.当然,但是再次 - 我不知道非实时处理在你的情况下是否真的很重要(我的盲目猜测 - 它没有),所以为什么真的很烦.如果你在这里节省几毫秒但是在整个解决方案的进一步维护上花费了很多时间,那么选择是非常明显的.

顺便说一句:以防万一 - 每当我写作时,mailbox我绝对意味着用户邮件的容器,而不是 mailbox文件格式.至于文件格式maildir(或某些东西)是更好,更好的选择.

  • 很棒的答案@Webnet. (2认同)