我有一封发给所有用户的邮件,每个用户发送一封电子邮件。
该功能有效,但我在网络应用程序上收到了一条丑陋的错误消息。在日志上,我得到了
2012-08-28T12:08:03+00:00 heroku[router]: Error H12 (Request timeout) -> POST afternoon-spring-6294.herokuapp.com/welcome/wall dyno=web.1 queue= wait= service=30000ms status=503 bytes=0
[...]
Sent mail to xxxx@xxxxx.xxxx (1708ms)
2012-08-28T12:08:31+00:00 app[web.1]: Redirected to http://afternoon-spring-6294.herokuapp.com/
2012-08-28T12:08:31+00:00 app[web.1]: Completed 302 Found in 58114ms (ActiveRecord: 8.9ms)
是否有解决方法(仅由33封电子邮件触发)?
Heroku获取所有运行时间超过30秒的进程,这意味着几乎任何通过mailgun或sendgrid等方式发送的批处理电子邮件都会因H12错误而终止。
有几种基本的处理方法,但都涉及到使事情更加异步。Heroku工作进程可以无限期运行,或者至少可以运行30秒以上。
传统的选择是使用队列——delayed_job非常简单,只需要一个数据库来支持它。Resque也很酷,但需要将Redis添加到混合中。还有许多更复杂的选择,但delayed_job非常简单。Railscasts可能是你的朋友,在这里想办法做到这一点。
另一种选择是使用工作进程直接处理电子邮件任务。例如,您可以使用一个工作人员使用rake任务每隔X分钟分批发送电子邮件。这是一种没有所有开销的队列。假设你需要发送一批邀请,你把状态为"未发送"的邀请写到一张表上,然后让一个rake任务弹出第一个并发送,重复直到完成。您基本上是在重新实现一个简单的队列,但可能会感觉更舒服。
就我个人而言,我会推迟工作,直到我需要更强大的东西。