php 如何每周发送 100,000 封电子邮件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3905734/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to send 100,000 emails weekly?
提问by xRobot
How can one send an email to 100,000 users on a weekly basis in PHP? This includes mail to subscribers using the following providers:
如何在 PHP 中每周向 100,000 个用户发送一封电子邮件?这包括使用以下提供商向订阅者发送的邮件:
- AOL
- G-Mail
- Hotmail
- Yahoo
- 美国在线
- 电子邮件
- 热信
- 雅虎
It is important that all e-mail actually be delivered, to the extent that it is possible. Obviously, just sending the mail conventionally would do nothing but create problems.
在可能的情况下,所有电子邮件都能够实际送达,这一点很重要。显然,仅按惯例发送邮件只会产生问题。
Is there a library for PHP that makes this simpler?
是否有一个 PHP 库可以使这更简单?
回答by Piskvor left the building
Short answer:While it's technically possible to send 100k e-mails each week yourself, the simplest, easiest and cheapest solution is to outsource thisto one of the companies that specialize in it (I didsay "cheapest": there's no limit to the amount of development time (and therefore money) that you can sink into this when trying to DIY).
简短回答:虽然技术上可以自己每周发送 10 万封电子邮件,但最简单、最简单和最便宜的解决方案是将其外包给一家专门从事此工作的公司(我确实说过“最便宜”:尝试 DIY 时可以投入的开发时间(以及金钱))。
Long answer:If you decide that you absolutely wantto do this yourself, prepare for a world of hurt (after all, this is e-mail/e-fail we're talking about). You'll need:
长答案:如果您决定自己绝对要这样做,请准备好迎接一个痛苦的世界(毕竟,这是我们正在谈论的电子邮件/电子邮件失败)。你需要:
- e-mail content that is notspam (otherwise you'll run into additional major roadblocks on every step, even legal repercussions)
- in addition, your content should be easy to distinguishfrom spam - that may be a bit hard to do in some cases (I heard that a certain pharmaceutical company had to all but abandon e-mail, as their brand names are quite common in spams)
- a configurable SMTP server of your own, one which won't buckle when you dump 100k e-mails onto it (your ISP's upstream server won't be sufficient here and you'll make the ISP violently unhappy; we used two dedicated boxes)
- some mail wrapper (e.g. PhpMailer if PHP's your poison of choice; using PHP's
mail()
is horrible enough by itself) - your own sender function to run in a loop, create the mails and pass them to the wrapper (note that you may run into PHP's memory limits if your app has a memory leak; you may need to recycle the sending process periodically, or even better, decouple the "creating e-mails" and "sending e-mails" altogether)
- 非垃圾邮件的电子邮件内容(否则您在每一步都会遇到额外的主要障碍,甚至是法律后果)
- 此外,您的内容应该很容易与垃圾邮件区分开来——这在某些情况下可能有点难(我听说某制药公司不得不放弃电子邮件,因为它们的品牌名称在垃圾邮件中很常见) )
- 你自己的一个可配置的 SMTP 服务器,当你把 10 万封电子邮件倾倒到它上面时不会扣(你的 ISP 的上游服务器在这里不够用,你会让 ISP 非常不高兴;我们用了两个专用的盒子)
- 一些邮件包装器(例如 PhpMailer,如果 PHP 是您选择的毒药;使用 PHP
mail()
本身就足够可怕) - 您自己的发送器函数循环运行,创建邮件并将它们传递给包装器(请注意,如果您的应用程序存在内存泄漏,您可能会遇到 PHP 的内存限制;您可能需要定期回收发送过程,甚至更好,将“创建电子邮件”和“发送电子邮件”完全分离)
Surprisingly, that was the easy part. The hard part is actually sending it:
令人惊讶的是,那是容易的部分。困难的部分实际上是发送它:
- some servers will ban you when you send too many mails close together, so you need to shuffle and watch your queue (e.g. send one mail to [email protected], then three to other domains, only then another to [email protected])
- you need to have correct PTR, SPF, DKIM records
- handling remote server timeouts, misconfigured DNS records and other network pleasantries
- handling invalid e-mails (and no, regex is the wrong tool for that)
- handling unsubscriptions (many legitimate newsletters have been reclassified as spam due to many frustrated users who couldn't unsubscribe in one step and instead chose to "mark as spam" - the spam filters do learn, esp. with large e-mail providers)
- handling bounces and rejects ("no such mailbox [email protected]","mailbox [email protected] full")
- handling blacklisting and removal from blacklists (Sure, you're not sending spam. Some recipients won't be so sure - with such large list, it willhappen sometimes, no matter what precautions you take. Some people (e.g. your not-so-scrupulous competitors) might even go as far to falsely report your mailings as spam - it does happen. On average, it takes weeks to get yourself removed from a blacklist.)
- 当您发送过多的邮件时,某些服务器会禁止您,因此您需要调整并观察您的队列(例如,将一封邮件发送到 [email protected],然后向其他域发送三封邮件,然后再向 [email protected] 发送另一封邮件)
- 你需要有正确的PTR、SPF、DKIM 记录
- 处理远程服务器超时、错误配置的 DNS 记录和其他网络问题
- 处理无效的电子邮件(不,正则表达式是错误的工具)
- 处理退订(由于许多沮丧的用户无法一步退订而是选择“标记为垃圾邮件”,许多合法的新闻通讯已被重新归类为垃圾邮件 - 垃圾邮件过滤器确实学习了,尤其是大型电子邮件提供商)
- 处理退回和拒绝(“没有这样的邮箱 [email protected]”,“邮箱 [email protected] 已满”)
- 处理黑名单和从黑名单中删除(当然,您不是在发送垃圾邮件。有些收件人不会那么确定 - 有这么大的名单,无论您采取什么预防措施,有时都会发生这种情况。有些人(例如您不那么确定) - 谨慎的竞争对手)甚至可能将您的邮件错误地报告为垃圾邮件 - 它确实发生了。平均而言,将自己从黑名单中删除需要数周时间。)
And to top it off, you'll have to manage the legal part of it (various federal, state, and local laws; and even different tangles of laws once you send outside the U.S. (note: you have no way of finding if [email protected] lives in Southwest Elbonia, the country with world's most draconian antispam laws)).
最重要的是,您必须管理其中的法律部分(各种联邦、州和地方法律;甚至在您发送到美国境外后还会遇到各种不同的法律问题(注意:如果 joe @hotmail.com 居住在 Elbonia 西南部,该国拥有世界上最严厉的反垃圾邮件法律))。
I'm pretty sure I missed a few heads of this hydra - are you still sure you want to do this yourself? If so, there'll be another wave, this time merely the annoying problems inherent in sending an e-mail. (You see, SMTP is a store-and-forward protocol, which means that your e-mail will be shuffled across many SMTP servers around the Internet, in the hope that the next one is a bit closer to the final recipient. Basically, the e-mail is sent to an SMTP server, which puts it into its forward queue; when time comes, it will forward it further to a different SMTP server, until it reaches the SMTP server for the given domain. This forward could happen immediately, or in a few minutes, or hours, or days, or never.) Thus, you'll see the following issues - most of which could happen en route as well as at the destination:
我很确定我错过了这个九头蛇的几个头 - 你仍然确定要自己做吗?如果是这样,将会有另一波浪潮,这一次只是发送电子邮件固有的恼人问题。(您看,SMTP 是一种存储转发协议,这意味着您的电子邮件将在 Internet 上的许多 SMTP 服务器之间混洗,希望下一个更接近最终收件人。基本上,电子邮件被发送到 SMTP 服务器,该服务器将其放入其转发队列;当时间到时,它将进一步转发到不同的 SMTP 服务器,直到它到达给定域的 SMTP 服务器。这种转发可能会立即发生,或在几分钟、几小时、几天或从不。)因此,您将看到以下问题 - 其中大部分可能发生在途中和目的地:
- the remote SMTP servers don't want to talk to your SMTP server
- your mails are getting marked as spam (
<blink>
is not your friend here, nor is<font color=...>
) - your mails are delivered days, even weeks late (contrary to popular opinion, SMTP is designed to make a best effort to deliver the message sometime in the future - not to deliver it now)
- your mails are not delivered at all (already sent from e-mail server on hop #4, not sent yet from server on hop #5, the server that currently holds the message crashes, data is lost)
- your mails are mangled by some braindead server en route (this one is somewhat solvable with base64 encoding, but then the size goes up and the e-mail looksmore suspicious)
- your mails are delivered and the recipients seem not to want them ("I'm sure I didn't sign up for this, I remember exactly what I did a year ago" (of course you do, sir))
- users with various versions of Microsoft Outlook and its specialhandling of Internet mail
- wizard's apprentice mode (a self-reinforcing positive feedback loop - in other words, automated e-mails as replies to automated e-mails as replies to...; you reallydon't want to be the one to set this off, as you'd anger half the internet at yourself)
- 远程 SMTP 服务器不想与您的 SMTP 服务器通信
- 您的邮件被标记为垃圾邮件(
<blink>
这里不是您的朋友,也不是<font color=...>
) - 您的邮件送达数天,甚至数周后(与流行观点相反,SMTP 旨在尽最大努力在未来某个时间传递邮件 - 而不是现在传递)
- 您的邮件根本没有送达(已经从第 4 跳的电子邮件服务器发送,尚未从第 5 跳的服务器发送,当前保存邮件的服务器崩溃,数据丢失)
- 你的邮件在途中被一些脑残服务器弄乱了(这个有点可以用 base64 编码解决,但随后大小增加,电子邮件看起来更可疑)
- 您的邮件已送达,但收件人似乎不想要它们(“我确定我没有注册此邮件,我完全记得我一年前所做的事情”(您当然知道,先生))
- 使用各种版本的 Microsoft Outlook 及其对 Internet 邮件的特殊处理的用户
- 向导的学徒模式(一种自我强化的正反馈循环——换句话说,自动电子邮件作为对自动电子邮件的回复作为对......的回复;你真的不想成为那个设置它的人,因为你会为自己激怒一半的互联网)
and it'll be yourjob to troubleshoot and solve this (hint: you can't, mostly). The people who run a legit mass-mailing businesses know that in the end you can't solve it, and that they can't solve it either - and they have the reasons well researched, documented and outlined (maybe even as a Powerpoint presentation - complete with sounds and cool transitions - that your bosses can understand), as they've had to explain this a million times before. Plus, for the problems that are actually solvable, they know very well how to solve them.
解决和解决这个问题将是你的工作(提示:你不能,大多数情况下)。经营合法的群发邮件业务的人知道,最终你无法解决它,他们也无法解决它——并且他们对原因进行了充分研究、记录和概述(甚至可能作为 Powerpoint 演示文稿) - 完整的声音和很酷的过渡 - 你的老板可以理解),因为他们之前已经解释过一百万次了。另外,对于实际可以解决的问题,他们非常了解如何解决。
If, after all this, you are not discouraged and still want to do this, go right ahead: it's even possible that you'll find a better way to do this. Just know that the road ahead won't be easy - sending e-mail is trivial, getting it delivered is hard.
如果在这一切之后,您并不气馁并且仍然想要这样做,请继续:您甚至可能会找到更好的方法来做到这一点。要知道前方的道路并不容易 - 发送电子邮件是微不足道的,交付它却很难。
回答by sohtimsso1970
People have recommended MailChimp which is a good vendor for bulk email. If you're looking for a good vendor for transactional email, I might be able to help.
人们推荐了 MailChimp,它是批量电子邮件的好供应商。如果您正在寻找交易电子邮件的优秀供应商,我可能会提供帮助。
Over the past 6 months, we used four different SMTP vendors with the goal of figuring out which was the best one.
在过去的 6 个月里,我们使用了四个不同的 SMTP 供应商,目的是找出最好的一个。
Here's a summary of what we found...
这是我们发现的摘要...
- Cheapest around
- No analysis/reporting
- No tracking for opens/clicks
- Had slight hesitation on some sends
- 周边最便宜
- 无分析/报告
- 不跟踪打开/点击
- 对某些发送略有犹豫
- Very cheap, but not as cheap as AuthSMTP
- Beautiful cpanel but no tracking on opens/clicks
- Send-level activity tracking so you can open a single email that was sent and look at how it looked and the delivery data.
- Have to use API. Sending by SMTP was recently introduced but it's buggy. For instance, we noticed that quotes (") in the subject line are stripped.
- Cannot send any attachment you want. Must be on approved list of file types and under a certain size. (10 MB I think)
- Requires a set list of from names/addresses.
- 非常便宜,但不如 AuthSMTP 便宜
- 漂亮的 cpanel 但没有跟踪打开/点击
- 发送级别的活动跟踪,因此您可以打开已发送的单个电子邮件并查看它的外观和交付数据。
- 必须使用 API。最近引入了通过 SMTP 发送,但它有问题。例如,我们注意到主题行中的引号 (") 被删除了。
- 无法发送您想要的任何附件。必须在批准的文件类型列表中并且在一定大小以下。(我认为 10 MB)
- 需要一组来自姓名/地址的列表。
- Expensive in relation to the others – more than 10 times in some cases
- Ugly cpanel but great tracking on opens/clicks with email-level detail
- Had hesitation, at times, when sending. On two occasions, sends took an hour to be delivered
- Requires a set list of from name/addresses.
- 与其他人相比昂贵——在某些情况下超过 10 倍
- 丑陋的 cpanel 但很好地跟踪打开/点击与电子邮件级别的详细信息
- 发送时有时会犹豫。有两次,发送需要一个小时才能送达
- 需要一组来自姓名/地址的列表。
- Not quite a cheap as AuthSMTP but still very cheap. Many customers can exist on 200 free sends per day.
- Decent cpanel but no in-depth detail on open/click tracking
- Lots of API options. Options (open/click tracking, etc) can be custom defined on an email-by-email basis. Inbound (reply) email can be posted to our HTTP end point.
- Absolutely zero hesitation on sends. Every email sent landed in the inbox almost immediately.
- Can send from any from name/address.
- 不像AuthSMTP那么便宜,但仍然很便宜。许多客户每天可以免费发送 200 次。
- 不错的 cpanel,但没有关于打开/点击跟踪的深入细节
- 很多 API 选项。选项(打开/点击跟踪等)可以在逐个电子邮件的基础上自定义定义。入站(回复)电子邮件可以发布到我们的 HTTP 端点。
- 发送时绝对零犹豫。发送的每封电子邮件几乎立即进入收件箱。
- 可以从任何名称/地址发送。
Conclusion
结论
SendGrid was the best with Postmark coming in second place. We never saw any hesitation in send times with either of those two - in some cases we sent several hundred emails at once - and they both have the best ROI, given a solid featureset.
SendGrid 是最好的,Postmark 排在第二位。我们从未发现这两者在发送时间上有任何犹豫——在某些情况下,我们一次发送了数百封电子邮件——而且鉴于可靠的功能集,它们都具有最佳的投资回报率。
回答by ethanpil
Here is what I did recently in PHP on one of my bigger systems:
这是我最近在我的一个更大的系统上用 PHP 做的事情:
User inputs newsletter text and selects the recipients (which generates a query to retrieve the email addresses for later).
Add the newsletter text and recipients query to a row in mysql table called *email_queue*
- (The table email_queue has the columns "to" "subject" "body" "priority")
I created another script, which runs every minute as a cron job. It uses the SwiftMailerclass. This script simply:
during business hours, sends all email with priority == 0
after hours, send other emails by priority
用户输入时事通讯文本并选择收件人(这会生成查询以检索电子邮件地址以备后用)。
将时事通讯文本和收件人查询添加到名为 *email_queue* 的 mysql 表中的一行
- (表 email_queue 有列“to”“subject”“body”“priority”)
我创建了另一个脚本,它每分钟作为一个 cron 作业运行。它使用SwiftMailer类。这个脚本很简单:
在工作时间,发送优先级 == 0 的所有电子邮件
下班后,优先发送其他电子邮件
Depending on the hosts settings, I can now have it throttle using standard swiftmailers plugins like antiflood and throttle...
根据主机设置,我现在可以使用标准的 swiftmailers 插件(如 antiflood 和油门)来限制它...
$mailer->registerPlugin(new Swift_Plugins_AntiFloodPlugin(50, 30));
and
和
$mailer->registerPlugin(new Swift_Plugins_ThrottlerPlugin( 100, Swift_Plugins_ThrottlerPlugin::MESSAGES_PER_MINUTE ));
etc, etc..
等等等等。
I have expanded it way beyond this pseudocode, with attachments, and many other configurable settings, but it works very well as long as your server is setup correctly to send email. (Probably wont work on shared hosting, but in theory it should...) Swiftmailer even has a setting
我已经超出了这个伪代码,使用附件和许多其他可配置的设置对其进行了扩展,但只要您的服务器设置正确以发送电子邮件,它就可以很好地工作。(可能不适用于共享主机,但理论上它应该......)Swiftmailer 甚至有一个设置
$message->setReturnPath
Which I now use to track bounces...
我现在用它来跟踪反弹...
Happy Trails! (Happy Emails?)
快乐轨迹!(快乐的电子邮件?)