2015年9月4日 星期五

[RoR]非同步處理-Sidekiq

在使用Web Application時偶而會有執行一支報表或是匯入資料時,整個系統就卡死在那邊的情況,這是因為要執行的request運算時間太久,造成session要等待request完成,結果除了會造成使用觀感不佳外,也有可能會影響整體的performance。這次的專案因為會進行大量資料的匯入,所以特別了解了一下Sidekiq的使用方法。

運作原理

Sidekiq是搭配Redis來儲存Job,而Redis是一套高性能的In-Memory Key-Value儲存系統。不過我對Redis的了解也就僅止於此,有機會再深入研究看看。

在使用Sidekiq之前必須先安裝Redis。我使用的是LinuxMint 17,屬於Ubuntu系的環境,安裝Redis也很簡單,只要輸入
sudo apt-get install redis-server

Sidekiq實作

步驟1:安裝sidekiq,在Gamfile中新增以下指令後,執行bundle install
gem 'sidekiq'
步驟2:定義config檔,讓ActiveJob知道要使用sidekiq,可以在/config/environments/development.rb或production.rb或直接定義在application.rb都可以,視需求來決定。
步驟3:再接著新增一行設定讓Rails可以找到job檔案。
require File.expand_path('../boot', __FILE__)

require 'rails/all'

Bundler.require(*Rails.groups)

module KennyTest
  class Application < Rails::Application
    # Do not swallow errors in after_commit/after_rollback callbacks.
    config.active_record.raise_in_transactional_callbacks = true
    config.active_job.queue_adapter = :sidekiq  #步驟2新增此行
    config.eager_load_paths += %W( #{config.root}/app/jobs ) #步驟3新增此行
  end
end
步驟4:設定Sidekiq初始化,在config/initializers/新增一個sidekiq.rb
Sidekiq.configure_server do |config|
  config.redis = { url: 'redis://localhost:6379/5', namespace: "activejob-sample" }
end

Sidekiq.configure_client do |config|
  config.redis = { url: 'redis://localhost:6379/5', namespace: "activejob-sample" }
end
步驟5:用rails g job test建立一個Job
步驟6:輸入要求Job要做的事
class TestJob < ActiveJob::Base
  queue_as :default

  def perform(*args)
    #新增此行
    Rails.logger.debug "#{self.class.name}: I'm performing my job with arguments: #{args.inspect}"
  end
end
步驟7:在新的Terminal啟動sidekiq,執行
bundle exec sidekiq
步驟8:在需要執行非同步的地方使用以下程式,就會將Job排進sidekiq
TestJob.perform_later 
或是在Terminal執行,效果同上
rails runner "TestJob.perform_later(1,2,3)"

執行畫面


備註

當Sidekiq遇到錯誤或Bug中斷處理過程了,這時開發人員通常會按下Ctrl+C中斷Sidekiq,但是要注意原本出錯的Job並不會從Redis Queue中移除,而是會再Sidekiq開起來後等待一段時間Retry。一方面為了避免Queue中存放了太多蠢蠢欲動的僵屍Job,一方面也要防止耗費大量時間的Job再起浪費資源,所以當中斷了Sidekiq之後必須要清除Queue中的Job,主要作法有兩種,這裡只介紹從terminal下指令的清除方式,輸入如下指令
redis-cli -n flushdb
redis-cli flushall

參考資料




沒有留言: