你如何使用capistrano进行滚动部署?

chr*_*mer 5 deployment capistrano load-balancing ruby-on-rails amazon-ec2

我们在负载均衡器后面有2个实例,与乘客一起运行相同的rails应用程序.部署时,服务器启动时间会导致请求超时.因此,我们有一个脚本可以单独更新每个Web服务器,方法是从LB中取出一个,使用上限进行部署,测试动态页面加载,然后将其重新放回LB.

我们怎样才能让capistrano用一个命令为我们做这个?我已经能够将其设置为同时部署到所有实例,但它们都会同时重新启动并导致站点不可用20秒.

我在这里错过了什么?这似乎应该是一种常见的模式.

rin*_*ter 3

实际上,在 capistrano 中序列化部署并不是那么简单,它喜欢并行化服务器之间的所有操作。重申一下这个问题,您似乎有一些服务器,并且希望按顺序使每台服务器脱机以更新部署。

诀窍是覆盖deploy:create_symlink部署配置中的任务:

def perform_task_offline options
  sudo "take_this_server_offline", options
  yield
  sudo "put_this_server_online", options
end

def create_symlink_task options
  # does what your existing deploy:create_symlink did, something like:
  run "rm -f /web/current && ln -s #{release_path} /web/current", options
end

namespace :deploy do

  task :create_symlink, {once: true, except: {no_release: true}} do
    deployed_servers = Array.new

    roles[:app].servers.each do |current_server|
      options = {hosts: current_server}
      deployed_servers.push current_server
      perform_task_offline(options) { create_symlink_task options }
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

在这种情况下,perform_task_offline包括在指定的服务器上执行的命令,options将其从负载均衡器中删除,而它yield是包含的块create_symlink_task,这会创建部署符号链接。

然后,您应该能够运行标准cap命令进行部署,并且您将看到服务器依次脱机,创建“当前”符号链接,然后重新启动。

请注意,上面的代码跟踪已成功部署到的服务器deployed_servers。如果您希望能够仅在先前部署到的服务器上回滚活动的失败部署(即,失败发生在部署本身期间),则需要在块内有一个类似的循环on_rollback do,但仅在deployed_servers