Ruby On Rails实战:给应用添加delayed_job

郁吉星
2023-12-01

什么是delayed_job

"dekayed_job"是一个ruby gem,在Rails环境中用来执行任务的后台进程,用来增加页面渲染的速度。Delayed::Job允许将任务转至后台异步处理。

为什么需要delayed_job

试想以下场景:

  • 一个请求需要很长处理时间才能返回
  • 大数据需要定时更新

如果不用delayed_job, 则会出现:

  • 返回时间很长,用户体验差
  • 需要人为触发,效率低

有了delayed_job, 则可以让delayed_job在后台处理。

应用delayed_job

  • 准备Ruby On Rails测试用code
    git clone https://github.com/testcara/ROR_Blog.git
  • 在Gemfile中添加delayed_job gem
    gem 'delayed_job_active_record'
    
  • 安装gem包
    bundle install --without production
  • 生成运行后台Job所需要的相应的文件
    $ rails g delayed_job:active_record
    Running via Spring preloader in process 7751
          create  bin/delayed_job
           chmod  bin/delayed_job
          create  db/migrate/20181225082621_create_delayed_jobs.rb
    

    生成的这两个文件:

    1. delayed_job: 执行在queue中的jobs

    2. db/migrate/*.rb: 用来创建db去存储job信息(priority, attempts, handler, last_error, run_at, queue等

  • 执行db migration
    $ rake db:migrate
    == 20181225082621 CreateDelayedJobs: migrating ================================
    -- create_table(:delayed_jobs, {:force=>true})
       -> 0.0030s
    -- add_index(:delayed_jobs, [:priority, :run_at], {:name=>"delayed_jobs_priority"})
       -> 0.0005s
    == 20181225082621 CreateDelayedJobs: migrated (0.0038s) =======================
    
    [Click and drag to move]
    ​
  • 更新application.rb

    config.active_job.queue_adapter = :delayed_job
  • 运行delayed_job

    bin/delayed_job start
    # If there is no error, you would get one pid. Otherwise, check the error.
    # Usually, we need 'daemon' gem file to run the job. we use the way in the production mode
    
    # The another way to trigger delayed_jobs is to run:
    # rake jobs:work
    # we use it in the development mode 
  • 将tasks改为delayed tasks

    $ # Previously, users can update posts instantly.
    $ # If we make the 'post.update' action as one delayed action 'post.delay.update', then we can update the post successfully but in fact the real update action is not triggered instantly but is inserted to delayed_job queues.
    $ git diff app/controllers/posts_controller.rb
    diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb
    index 7f02217..ed31a7f 100644
    --- a/app/controllers/posts_controller.rb
    +++ b/app/controllers/posts_controller.rb
    @@ -32,7 +32,7 @@ class PostsController < ApplicationController
            end
     
            def update
    -               if @post.update(post_params)
    +               if @post.delay.update(post_params)
                            redirect_to @post, notice: "Update successfully!"
                    else
                            render 'edit'
    

     从log里面我们可以看到不断有delayed job在执行queues中操作。本文的案例不是一个很好的案例,因为更新log实时操作更合适。

  • 配置delayed_jobs

    $ # Here just one config delayed_jobs, for more advanced usage, you can read following content
    $ cat config/initializers/delayed_job_config.rb
    # whether the job will be clean if it is failed
    Delayed::Worker.destroy_failed_jobs = false
    # If there is no jobs lefe, sleep 60s then to check the queue
    Delayed::Worker.sleep_delay = 60
    # If the job is failed at the first time, try more 2 times
    Delayed::Worker.max_attempts = 3
    # If the unfinished job has been kept for 5 minutes, let us mark it as 'failed'
    Delayed::Worker.max_run_time = 5.minutes
    # If there are available jobs, read the first 10 ones from the queue 
    Delayed::Worker.read_ahead = 10
    # By default all jobs will be queued without a named queue. A default named queue can be specified by using the following parameter
    Delayed::Worker.default_queue_name = ‘default’
    # Testing env does not support delayed_job
    Delayed::Worker.delay_jobs = !Rails.env.test?
    # Make the worker to raise a SignalException causing the running job to abort and be unlocked, which makes the job available to other workers. 
    Delayed::Worker.raise_signal_exceptions = :term
    # Delayed jobs log path
    Delayed::Worker.logger = Logger.new(File.join(Rails.root, ‘log’, ‘delayed_job.log’))
    
    

     

 

 类似资料: