使用Rails的ActiveJob

在Rails中,用于使用后台作业的机制是Active Job。通过使用Active Job,可以在HTTP的主线程中立即返回响应,并且可以在后台执行繁重的处理。

因此,我們立即進行設定。Active Job只提供了一個框架,用於執行基本的後台作業。可以在設定中指定要執行實際後台作業的後端。似乎有多個後端可用,但目前的事實是sidekiq。sidekiq在rails之外以獨立的進程運行,通過redis進行作業交互。這就是一個簡單的消息佇列。

在中国有一种名为Resque的后端,它也通过redis来执行任务,但根据项目页面上的说明,它只在redis 1.x上进行了测试,并且似乎会定期轮询redis以检查任务的存在。这种方法有点过时了。

安裝

我們需要安裝和設置Redis和Sidekiq。Redis是一個高效的內存數據庫,可以用於快速存儲和查詢數據。同時,Sidekiq是一個用於處理後台作業的工具,可以幫助我們提高應用程序的性能和效率。

$ brew install redis

那么,我们就开始安装吧。然后,只需要做一些后续的操作。

$ redis-server /usr/local/etc/redis.conf

启动Redis。

Rails端添加以下内容到Gemfile并安装。

gem 'redis'
gem 'connection_pool'
gem 'sidekiq'
gem 'sinatra', require: false

配置相关

跟前一篇文章一样,我们来配置Redis。

首先,在config/redis.yml文件中添加以下内容。

default: &default
  host: localhost
  port: 6379

development:
  <<: *default

test:
  <<: *default

production:
  <<: *default
  host: production-redis-server

接下来,我们将对config/initializers/sidekiq.rb文件进行sidekiq的配置如下。

# Load the redis.yml configuration file
redis_config = YAML.load_file(Rails.root + 'config/redis.yml')[Rails.env]

redis_conn = proc {
  Redis.new host: redis_config['host'], port: redis_config['port']
}
Sidekiq.configure_client do |config|
  config.redis = ConnectionPool.new(size: 5, &redis_conn)
end
Sidekiq.configure_server do |config|
  config.redis = ConnectionPool.new(size: 25, &redis_conn)
end

连接池的大小已经固定,但也可以在redis.yml文件中进行设置。

将worker的文件放置在app/workers目录中。在config/application.rb中设置自动加载该目录。并且配置使用sidekiq作为后端。

config.autoload_paths << "#{config.root}/app/workers"
config.active_job.queue_adapter = :sidekiq

开始

当设置完成后,我们会启动sidekiq和rails一起运行。

$ bundle exec sidekiq

在选项中指定日志文件和进行守护进程化是可行的。当在生产环境运行时,需要将”-e production”选项添加进去。

如果更改了工作进程,它不会自动重新加载,因此需要重新启动进程。

工人的设置

工作岗位使用worker指定。以下代码是将输出发送到标准输出的worker。

class PrintWoker
  include Sidekiq::Worker

  def perform(s)
    print s
  end
end

只需要输出通过参数传递的字符串。在worker中,可以正常处理Active Record等。

以下是用于执行worker的Rails代码。您可以在控制器等地方进行如下编写。

PrintWorker.perform_async "Hello, World"

通过这个简单的代码,可以实现异步执行worker。直接调用perform函数,可以在主线程中直接执行。需要注意的是,参数只能处理简单类型的数据,例如字符串和数字等。

除了这个之外,还可以控制在指定的时间执行作业或者在几分钟后执行作业等等,可以控制作业的执行时机。

ActionMailer 动作邮件发送器

ActionMailer也支持Active Job。将原本执行deliver_now的代码改为deliver_later后,将会以后台任务的形式异步执行。

要让sidekiq处理邮件队列,需要使用以下命令启动,因为sidekiq默认只处理默认队列。

$ bundle exec sidekiq -q default -q mailers
bannerAds