如何正常重启延迟

我想知道在推出新代码后,如何正常重启delayed_job使用者的最佳方式是什么? 我推capistrano的代码,我知道有命令可以重新启动,但是如果当前正在运行的作业,该命令要么挂起(并且我的部署需要永久),要么强行退出当前正在运行的作业,并且丢失数据。

理想情况下,我希望我的部署发生如下所示:

  • 现有的delayed_job消费者正在使用版本1代码运行
  • 我运行cap deploy和版本2代码推出到新的服务器
  • 在部署期间,我们触摸一个文件来告诉delayed_job在处理当前作业完成后重新启动。 这可以通过一系列不同的方式完成,但我认为这与乘客如何优雅地重新启动相似
  • 现有的delayed_job消费者继续使用版本1代码完成当前工作
  • 当前工作结束,delayed_job消费者认为在继续处理工作之前需要重新启动自己
  • delayed_job消费者自动重新启动,现在运行版本2代码
  • delayed_job消费者继续处理作业,现在运行在版本2代码上
  • 我试图通过检查代码的当前修订版插入一些代码重新启动之前,通过检查代码的当前版本,但每次我这样做,它只是死,并没有实际上重新启动任何东西。 示例代码如下:

    def before(job)
      # check to make sure that the version of code here is the right version of code
      live_git_hash = LIVE_REVISION
      local_git_hash = LOCAL_REVISION
    
      if live_git_hash != local_git_hash
        # get environment to reload in
        environment = Rails.env # production, development, staging
    
        # restart the delayed job system
        %x("export RAILS_ENV=#{environment} && ./script/delayed_job restart")
      end
    end
    

    它检测到它很好,但它在shell调用中死亡。 有任何想法吗?

    谢谢!


    提出了一个可行的解决方案。

    我有一个基类,所有延迟作业都从被调用的BaseJob继承而来:

    class BaseJob
      attr_accessor :live_hash
    
      def before(job)
        # check to make sure that the version of code here is the right version of code
        resp = HTTParty.get("#{Rails.application.config.root_url}/revision")
        self.live_hash = resp.body.strip
      end
    
      def should_perform()
        return self.live_hash == GIT_REVISION
      end
    
      def perform()
        if self.should_perform == true
          self.safe_perform()
        end
      end
    
      def safe_perform()
        # override this method in subclasses
      end
    
      def success(job)
        if self.should_perform == false
          # log stats here about a failure
    
          # enqueue a new job of the same kind
          new_job = DelayedJob.new
          new_job.priority = job.priority
          new_job.handler = job.handler
          new_job.queue = job.queue
          new_job.run_at = job.run_at
          new_job.save
          job.delete
    
          # restart the delayed job system
          %x("export RAILS_ENV=#{Rails.env} && ./script/delayed_job stop")
        else
          # log stats here about a success
        end
      end
    
    end
    

    所有基类都从BaseJob继承并重写safe_perform以实际完成其工作。 关于上述代码的一些假设:

  • Rails.application.config.root_url指向您的应用程序的根目录(即:www.myapp.com)
  • 有一个路径暴露为/revision (即:www.myapp.com/revision)
  • 你的应用知道有一个叫做GIT_REVISION的全局常量
  • 我最终做的是将git rev-parse HEAD的输出放在一个文件中,并用代码推送它。 它在启动时会被加载,因此可以在Web版本以及delayed_job使用者中使用。

    当我们通过Capistrano部署代码时,我们不再停止,启动或重新启动delayed_job使用者。 我们在每分钟运行的使用者节点上安装一个cronjob,并确定是否正在运行delayed_job进程。 如果不是,那么会产生一个新的。

    作为所有这些的结果,满足以下所有条件:

  • 推送代码不会等待delayed_job重新启动/强制终止。 当新代码被推送时,正在运行的现有作业将被保留。
  • 如果消费者运行旧代码,我们可以检测到工作何时开始。 这项工作得到重视,消费者自杀。
  • 当delayed_job死亡时,通过cronjob产生一个新的代码(通过启动delayed_job的性质,它具有新的代码)。
  • 如果您对杀死delayed_job用户偏执狂,请安装与cron作业相同的nagios检查,但在delayed_job进程未运行5分钟时发出警报。
  • 链接地址: http://www.djcxy.com/p/75373.html

    上一篇: How to gracefully restart delayed

    下一篇: c++ armadillo