如果你有使用过,resque,,就会发现基本每个这种消息队列的gem的使用方法都是类似的,里面的概念也是差不多,也就是说,学会了queue_classic就等于会其中三种,只要掌握思想就好了。

假如我们已经有一个rails项目了。

在Gemfile添加下面这行。

执行

正如我们上面所说的,任务是需要存储的。所以要创建相应的表来存。

  1. # 创建queue_classic_jobs表
  2. rails generate queue_classic:install
  3. # username替换为你自己的数据库的用户名,password是数据库的密码,rails365_dev是数据库名
  4. export QC_DATABASE_URL="postgres://username:password@localhost/rails365_dev"
  5. bundle exec rake db:migrate

我们先在rails console里测试。

前面说过,消息队列是跑在一个进程里的。所以要启动那个进程。

  1. bundle exec rake qc:work

你会发现delayed_job,sidekiq也是差不多的启动方法。

启动好后,我们进入rails console中,执行下面这行语句。

  1. rails365 git:(master) rails c
  2. Loading development environment (Rails 4.2.3)
  3. 2.2.2 :001 > QC.enqueue("Kernel.puts", "hello world")

你会在进程里看到类似这样的输出,就说明成功了。

  1. rails365 git:(master) bundle exec rake qc:work
  2. hello world

QC.enqueue就是后面的命令加上参数作为任务push到队列中。

上面只是个最简单的例子,还有可以在指定时间,指定队列来执行,具体更为详细的命令要看官方的readme文档。

如果需要调试或查看日志,可以开启调试功能,有两种不同的日志,分别是:

在运行rake qc:work之前运行,具体的效果,尝试下就知道的。

以为例,是一个放博客的网站,文章是存放在articles这张表,当时为了查看哪篇文章最受欢迎,就在articles存了一个字段叫visit_count,但每次用户查看文章时,就会往这个字段加1。这个动作是用rails的ActiveSupport::Notifications配合sidekiq的消息队列来做的,现在要改成用queue_classic来做。

我们来看下相关的代码。

  1. # app/workers/update_article_visit_count_worker.rb
  2. class UpdateArticleVisitCountWorker
  3. def perform(article_id)
  4. logger.info 'update article visit count begin'
  5. @article = Article.find(article_id)
  6. @article.visit_count += 1
  7. @article.save!(validate: false)
  8. logger.info 'update article visit count end'
  9. end
  10. end
  1. ActiveSupport::Notifications.subscribe "process_action.action_controller" do |name, started, finished, unique_id, payload|
  2. Rails.logger.info payload
  3. if payload[:controller] == "ArticlesController" && payload[:action] == "show"
  4. UpdateArticleVisitCountWorker.perform_async(payload[:params]["id"]) if payload[:params]["id"].present?
  5. end
  6. end

上文提过,queue_classic主要是利用QC.enqueue这条命令把任务push到队列中的。只需要把这行UpdateArticleVisitCountWorker.perform_async(payload[:params]["id"]) if payload[:params]["id"].present?改成我们需要的就可以了。

把增加visit_count的值的逻辑移动model中去,然后在用QC.enqueue中调用就好了。

改造之后是这样的。

  1. # config/initializers/notification.rb
  2. ActiveSupport::Notifications.subscribe "process_action.action_controller" do |name, started, finished, unique_id, payload|
  3. Rails.logger.info payload
  4. if payload[:controller] == "ArticlesController" && payload[:action] == "show"
  5. QC.enqueue "Article.update_article_visit_count",payload[:params]["id"] if payload[:params]["id"].present?
  6. end
  7. end

现在需要重启下rails serverbundle exec rake qc:work

重启rails server运行好export QC_DATABASE_URL="postgres://username:password@localhost/rails365_dev"这个命令。

为了让rake qc:work更能明显地看到日志信息,在运行rake qc:work前先执行export QC_MEASURE="true"

现在可以去页面上测试的。

第一点是关于环境变量,也就是QC_DATABASE_URLQC_MEASURE、这三个,当部署到线上环境时,就要把这三个变量写进shell的配置文件,如比ubuntu系统,就写进~/.bashrc_profile就好了。

完结。