当Unicorn主机完成重启时是否可以发送通知?

时间:2013-11-06 23:39:13

标签: ruby deployment nginx unicorn

我在nginx + unicorn后面运行了一系列Rails / Sinatra应用程序,零停机时间部署。我喜欢这种设置,但Unicorn需要一段时间才能完成重启,因此我希望在完成后发送一些通知。

我在Unicorn docs中找到的唯一回调与工人分叉有关,但我不认为这些可以为此工作。

这就是我从赏金中寻找的东西:旧的独角兽大师启动新的主人,然后启动其工人,然后旧的主人停止其工人并让新的主人接管。我希望在切换完成后执行一些ruby代码。

理想情况下,我不想实施任何复杂的流程监控来实现这一目标。如果这是唯一的方式,那就这样吧。但是在我走这条路之前,我正在寻找更简单的选择。

2 个答案:

答案 0 :(得分:2)

我之前已经建立了这个,但它并不完全简单。

第一步是添加一个API,返回部署的当前代码版本的git SHA。例如,您部署AAAA。现在您部署BBBB并将返回。例如,假设您添加了返回SHA的api “/ checks / version”

这是一个用于实现此API的示例Rails控制器。它假设存在capistrano REVISION文件,并在app加载时将当前版本SHA读入内存:

class ChecksController
  VERSION = File.read(File.join(Rails.root, 'REVISION')) rescue 'UNKNOWN'

  def version
    render(:text => VERSION)
  end
end

然后,您可以通过API轮询本地独角兽的SHA,并等待它更改为新版本。

以下是使用Capistrano的示例,它将正在运行的应用版本SHA与新部署的应用版本SHA进行比较:

namespace :deploy do
  desc "Compare running app version to deployed app version"
  task :check_release_version, :roles => :app, :except => { :no_release => true } do
    timeout_at = Time.now + 60
    while( Time.now < timeout_at) do
      expected_version = capture("cat /data/server/current/REVISION")
      running_version = capture("curl -f http://localhost:8080/checks/version; exit 0")

      if expected_version.strip == running_version.strip
        puts "deploy:check_release_version: OK"
        break
      else
        puts "=[WARNING]==========================================================="
        puts "= Stale Code Version"
        puts "=[Expected]=========================================================="
        puts expected_version
        puts "=[Running]==========================================================="
        puts running_version
        puts "====================================================================="
        Kernel.sleep(10)
      end
    end
  end
end

您需要调整轮询的超时/重试次数,以匹配您的平均应用启动时间。此示例假定为capistrano结构,其中app为/data/server/current,端口为8080上的本地独角兽。

答案 1 :(得分:0)

如果您拥有对该框的完全访问权限,则可以编写Unicorn脚本脚本以启动另一个脚本,该脚本循环检查将链接到正在运行的进程的/proc/<unicorn-pid>/exe

请参阅:Detect launching of programs on Linux platform

<强>更新

根据问题的变化,我看到两个选项 - 两者都不是很好,但它们仍然是选项......

  1. 你可以有一个每分钟运行一个Ruby脚本的cron作业监视PID目录mtime,然后确保存在PID文件(因为这会告诉你文件在目录中已经改变,而且过程是如果两个条件都为真,则执行其他代码。再次,这是丑陋的,并且是每分钟运行的一个cron,但它是最小的设置。

  2. 我知道你想避免复杂的监控,但这就是我尝试的方法......我会用monit来监控这些进程,当它们重新启动时,启动一个Ruby脚本睡眠(确保启动),然后检查进程的状态(可能再次使用monit本身)。如果这一切都正常返回,请执行其他Ruby代码。

  3. 选项#1不干净,但是当我编写monit选项时,我更喜欢它。