Nginx使用capistrano滚动重启Rails应用程序

时间:2011-07-07 15:15:15

标签: ruby-on-rails deployment nginx passenger capistrano

对于我的生活,我无法弄清楚如何正常工作。

问题类似于其他人的问题,例如:How to do a rolling restart of a cluster of mongrels

然而,我们使用的是Nginx / Passenger而不是Mongrel。

问题在于,如果我们使用此标准,则在部署时:重新启动任务:

task :restart, :roles => [:app], :except => {:no_release => true} do
  run "cd #{deploy_to}/current && touch tmp/restart.txt"
end

它触及每个Web服务器上的restart.txt文件,但是当前正在提供请求的任何乘客实例都需要在新的生成之前完成。这会造成严重的延迟,并导致我们的应用程序在一切都恢复的情况下最多可以使用2分钟。

为了解决该计划,请执行以下操作:

  1. 部署代码
  2. 转到服务器1,将其从负载均衡器中删除
  3. 在服务器1上重启nginx-passenger
  4. 等待60秒
  5. 将服务器1添加回负载均衡器
  6. 转到服务器2(重复步骤3 - 5)
  7. 为实现这一目标,我尝试了这个:

    (lb.txt是负载均衡器查找的文件)

    task :restart, :roles => [:app], :except => {:no_release => true} do
      servers = find_servers_for_task(current_task)
      servers.map do |s|
        run "cd #{deploy_to}/current && echo '' > public/lb.txt", :host => s.host
        run %Q{rvmsudo /etc/init.d/nginx-passenger restart > /dev/null}, :host => s.host
        sleep 60
        run "cd #{deploy_to}/current && echo 'ok' > public/lb.txt", :host => s.host
      end
    end
    

    这个几乎可以工作,但是,在部署期间,它似乎在:app角色中列出的每个服务器上运行一次服务器循环。我们目前有6个app服务器,因此循环运行6次,每个服务器重启nginx-passenger 6次。

    我只需要这个循环就可以运行一次。

    我知道似乎最终乘客会重新开始,但它们似乎还不存在。

    如果有帮助,我们正在使用Capistrano 2.x和Rails 3

    任何帮助都会很棒。

    感谢。

2 个答案:

答案 0 :(得分:6)

run "cd #{deploy_to}/current && echo 'ok' > public/lb.txt", :host => s.host

实际应该是:

run "cd #{deploy_to}/current && echo 'ok' > public/lb.txt", :hosts => s.host

答案 1 :(得分:2)

我遇到了这个带有滚动重启功能的gem capify-ec2。 capify-ec2 on github.

我即将安装并尝试一下。

以下是自述文件中描述滚动重启功能的内容:

“此功能允许您一次一个地将代码部署到实例,而不是同时部署。这对于在部署后可能需要更长时间启动的更复杂的应用程序非常有用.Capistrano将执行完整部署(包括任何自定义)钩子)针对单个实例,可选择对实例执行HTTP运行状况检查,然后在部署成功时继续执行下一个实例。

部署后会显示状态报告,指示部署成功,失败或未开始的实例。如果出现故障,可能需要手动采取进一步措施;例如,如果从ELB中删除实例(请参阅下面的“使用弹性负载均衡器”部分)并且部署失败,出于安全原因,实例将不会重新注册到ELB。“