Hack ar_mailer
前面说到使用rails发送邮件的问题,问题还没完,遇到大量邮件发送的时候,ActionMailer就处理不过来了。其实不用大量邮件发送,使用gmail发送邮件的时候反应也比较慢,怎么办呢?还好找到了一个叫ar_mailer的插件(在rubyforge上的rctool项目下)。
ar_mailer的思想其实很简单,就是你要发送邮件吧,好,我不管你发多少封,我把你的发件人、收件人、邮件内容全部存到数据库里,相当于一个队列,然后慢慢一封一封地发。这样就不会连半天服务器连不上结果发信失败了。而且这样有一个好处,用户那里反应很快,因为只有一个数据库操作的时间,这往往比连smtp服务器特别是远程的smtp服务器快多了。
好,我们就要使用ar_mailer了。首先按照文档里说的
ruby 代码
然后cd到我的rails项目目录下
ruby 代码
- ar_sendmail --create-migration
- ar_sendmail --create-model
然后把新建的Email那个model里面的class Emailer < ActionMailer::Base改成class Emailer < ActionMailer::ARMailer,然后在environment.rb里面加一句ActionMailer::Base.delivery_method = :activerecord
好了,可以运行ar_sendmail了,咦?怎么不成功?
我想在windows平台下,可能跟linux的环境有所区别,于是开始看原因。
我这里有几个问题(可能不会在所有地方都出现,也许有的是我误操作)
1.找不到ar_sendmail。这个好解决,把ar_mailer的文件都拷到action_mailer目录下。(比如我的就是把D:\InstantRails\ruby\lib\ruby\gems\1.8\gems\ar_mailer-1.1.0\lib\action_mailer下的ar_mailer.rb和ar_sendmail.rb拷贝到D:\InstantRails\ruby\lib\ruby\gems\1.8\gems\actionmailer-1.2.5\lib\action_mailer下)
2.数据库没有建立成功。我对migration不怎么会,于是就自己手工创建了,建了个emails表,ddl如下:
sql 代码
- CREATE TABLE `emails` (
- `id` int(10) unsigned NOT NULL auto_increment,
- `from` varchar(255) NOT NULL,
- `to` varchar(255) NOT NULL,
- `last_send_attempt` int(10) unsigned NOT NULL default '0',
- `mail` text NOT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8
总结一下,要做的事情:
1.安装ar_sendmail
2.创建emails表
3.创建Email这个Model
4.将从ActionMailer继承的Mailer改成从ARMailer继承(比如我的Mailer叫Notifier)
5.在environment.rb里面加上一句ActionMailer::Base.delivery_method = :activerecord,对了,原来的ActionMailer::Base.delivery_method = :msmtp可以去掉了
6.在rails项目的目录下运行ar_sendmail
好了,这下应该ok了吧,嗯,还是不行。。。仔细一看错误提示,发现ar_mailer还是用的smtp发信,去找本地邮件服务器。但是俺用的是gmail,咋办呢,动手hack吧。
其实ar_mailer这个plugin就2个文件,ar_mailer.rb和ar_sendmail.rb。我主要是要改发信机制的地方,就改ar_sendmail.rb了。
找到ar_sendmail.rb中的deliver方法
ruby 代码
- def deliver(emails)
- Net::SMTP.start server_settings[:address], server_settings[:port],
- server_settings[:domain], server_settings[:user],
- server_settings[:password],
- server_settings[:authentication] do |smtp|
- until emails.empty? do
- email = emails.shift
- begin
- res = smtp.send_message email.mail, email.from, email.to
- email.destroy
- log "sent email %011d from %s to %s: %p" %
- [email.id, email.from, email.to, res]
- rescue Net::SMTPFatalError => e
- log "5xx error sending email %d, removing from queue: %p(%s):\n\t%s" %
- [email.id, e.message, e.class, e.backtrace.join("\n\t")]
- email.destroy
- smtp.reset
- rescue Net::SMTPServerBusy, Net::SMTPUnknownError,
- Net::SMTPSyntaxError, TimeoutError => e
- email.last_send_attempt = Time.now.to_i
- email.save rescue nil
- log "error sending email %d: %p(%s):\n\t%s" %
- [email.id, e.message, e.class, e.backtrace.join("\n\t")]
- smtp.reset
- end
- end
- end
- end
看,用的Net::SMTP吧,好,我只需要调用msmtp就好了,改成这样:
ruby 代码
- def deliver(emails)
- until emails.empty? do
- email = emails.shift
- IO.popen("d:\\msmtp -t -C d:\\.msmtprc -a gmail --", "w") do |sm|
- sm.puts(email.mail.gsub(/\r/, ''))
- res = sm.flush
- email.destroy
- log "sent email %011d from %s to %s: %p" %
- [email.id, email.from, email.to, res]
- end
- end
- end
好了,可以发送邮件了,邮件多也不会把服务器压垮了,哈哈。当然,现在还有几个问题:
1.没有控制出错(我对ruby的异常机制不了解:P)。如果出错了,ar_mailer就会退出,然后我再重启一下ar_sendmail,反正没发送成功的邮件没有destroy。
2.ar_mailer一直运行,监控邮件发送。在linux下ar_sendmail &就好了,他自己运行,我就可以退出了。但是在windows下就得开一个命令行,让他一直跑着。有点丑陋,而且容易出意外。我试了下把ar_mailer装成一个服务,但是启动不了。如果能像mongrel_service那样就好了,这个,就只能等高手出招了。
分享到:
- 2006-12-09 00:48
- 浏览 4463
- 评论(2)
- 论坛回复 / 浏览 (2 / 6732)
- 查看更多
相关推荐
ResqueMailer 一个gem插件,允许ActionMailer准备的消息异步传递。 假设您正在使用进行后台作业。 请注意,Resque :: Mailer的最新(2.0+)版本仅适用于Rails 3.x或更高版本。 对于与Rails 2兼容的版本,在Gemfile中...
继承现有Rails邮件中的MandrillMailer类,以使用其基于模板的电子邮件通过Mandrill发送事务性电子邮件。 安装 将此行添加到您的应用程序的Gemfile中: gem 'mandrill_mailer' 然后执行: $ bundle install 或将其...
概述 每当resque作业失败时,使用resque-failed-job-mailer gem来发送电子邮件以及整个异常回溯。安装可以使用内置的Rails插件脚本来完成插件的安装。 从Rails应用程序的根目录发出以下命令: $ ./script/rails ...
该gem自动重写ActionMailer生成的绝对链接。 它拦截所有url_for调用(因此也拦截link_to调用),并更改最终URL,以将添加到您的URL中。 安装 将此行添加到您的应用程序的Gemfile中: gem 'google_analytics_mailer...
SendGrid ActionMailer 一个ActionMailer适配器,可使用SendGrid的HTTPS Web API(而不是SMTP)发送电子邮件。 与Rails 5和Sendgrid API v3兼容。 安装 将此行添加到您的应用... sendgrid_actionmailer_settings = {
ActionMailerMatchers提供RSpec匹配器以测试常见的ActionMailer功能。 安装 将此行添加到您的应用程序的Gemfile中: group :test do gem 'action_mailer_matchers' , '~> 1.0' end 然后执行: $ bundle install...
如果您发送大量电子邮件并想知道该特定用户收到了哪些电子邮件,这将非常有用。 一种简单的方法是在每个ActionMailer :: Base祖先方法的末尾放置一些SentMailLog.create()。 看起来不是真的DRY,但是可以使用。 ...
capybara-email, 使用Capybara测试你的ActionMailer和Mailer消息 CapybaraEmail 轻松测试 ActionMailer 和邮件在你的集成测试中安装将此行添加到你的应用程序的Gemfile中:gem 'capybara-email'然后执行: $ bund
用于通知的电子邮件通知程序,不依赖于 ActionMailer,可以在 Rails 之外使用,即与 Grape 一起使用。 截至目前,它仅支持文本电子邮件。 作为一种传递方法,它可以使用或或您定义的自定义方法。 为什么? 我已经...
电子邮件非常危险 - 从浏览器的安全性检查您的邮件模板。 安装 添加到您的Gemfile : gem "letter_bomb" , group : :development 并bundle 。 用法 在你的routes.rb安装引擎: if Rails . env . development? ...
email-spec, 在使用ActionMailer或者Pony的ruby 应用中,收集 testing/minitest匹配器的集合和用于测试电子邮件的Cucumber 步骤 电子邮件规范用于 RSpec 。MiniTest 和 Cucumber 步骤的匹配器集合,使测试邮件顺利...
用于ActionMailer的 SMTP API集成。 请上查看该协议的详细信息。 安装 将Mandriller宝石添加到您的Gemfile中。 gem "mandriller" 并运行bundle install 。 将以下内容添加到config/environments/任何环境设置中...
mail_safe 在开发使用ActionMailer的应用程序时,邮件保险箱提供了一个安全网。 它可以防止电子邮件逃逸。 一旦安装并配置了该gem,就可以确保您的应用不会将电子邮件发送到外部电子邮件地址。 取而代之的是,通常会...
尽管使用 Mass Mandrill 发送电子邮件看起来像使用 ActionMailer 发送电子邮件,但 Mass Mandrill 不依赖于 Rails,它可以在非 Rails 应用程序中使用。 Mass Mandrill 支持批量电子邮件发送和 Mandrill 模板。 要...
它提供了一个delivery_method基于SparkPost API,使越来越设置,并通过SparkPost在Rails应用程序相当简单发送电子邮件。 入门 将宝石添加到您的Gemfile gem 'sparkpost_rails' 然后运行bundle命令进行安装。 ...
actionmailer-2.3.5.gem
把它想象成 ActionMailer,但用于定时电子邮件序列。 它还可以执行其他操作,例如发送短信。 入门 开始使用 Heya 很容易: 安装 Heya gem 将此行添加到应用程序的 Gemfile 中: gem "heya" , github : "honey...
与ActionMailer一起使用时,它可与ActiveRecord Mailer和。 如果您要结合自动浏览器解决方案(例如Selenium)来测试电子邮件,则需要在测试环境中使用 。 (这是因为您的测试过程和服务器过程是不同的,因此需要...
送货上门这个插件满足了一个简单的需求:在开发或试生产中,你将能够控制你的应用程序发送的任何邮件的收件人,而不管真正的收件人是什么。 这个插件提供了一种方法来覆盖真实到:cc: 和 bcc: 收件人,并在交付时...
actionmailer-2.3.11 安装redmine必须的gem插件