当我使用 Capistrano 3.0.1 执行 cap production deploy 时,我正在尝试启动或重新启动 Unicorn。我有一些使用 Capistrano 2.x 使用的示例,例如:

namespace :unicorn do
  desc "Start unicorn for this application"
  task :start do
    run "cd #{current_path} && bundle exec unicorn -c /etc/unicorn/myapp.conf.rb -D"
  end
end

但是当我尝试在 Capistrano 3.x 的 run 中使用 deploy.rb 时,我得到一个未定义的方法错误。

以下是我尝试过的几件事:
# within the :deploy I created a task that I called after :finished
namespace :deploy do
...

  task :unicorn do
    run "cd #{current_path} && bundle exec unicorn -c /etc/unicorn/myapp.conf.rb -D"
  end

  after :finished, 'deploy:unicorn'

end

我也尝试将运行放在 :restart 任务中
namespace :deploy do
  desc 'Restart application'
  task :restart do

  on roles(:app), in: :sequence, wait: 5 do
    # Your restart mechanism here, for example:
    # execute :touch, release_path.join('tmp/restart.txt')
    execute :run, "cd #{current_path} && bundle exec unicorn -c /etc/unicorn/deployrails.conf.rb -D"
  end
end

如果我在本地 shell 中只使用 run "cd ... " then I'll get a 错误数量的参数(1 代表 0)`。

我可以从 ssh 的 VM shell 中使用 unicorn -c /etc/unicorn/deployrails.conf.rb -D 启动 unicorn 进程。

我可以使用 kill USR2 从 VM shell 终止主 Unicorn 进程,但即使该进程被终止,我也会收到错误消息。然后我可以使用 unicorn -c ... 再次启动该过程
$ kill USR2 58798
bash: kill: USR2: arguments must be process or job IDs

总的来说,我对 Ruby、Rails 和 Deployment 很陌生。我有一个带有 Ubuntu、Nginx、RVM 和 Unicorn 的 VirtualBox 设置,到目前为止我很兴奋,但这个真的让我很困惑,任何建议或见解都值得赞赏。

最佳答案

不能说任何关于 capistrano 3(我使用 2)的具体内容,但我认为这可能会有所帮助: How to run shell commands on server in Capistrano v3?
我也可以分享一些与 unicorn 相关的经验,希望能有所帮助。

我假设您想要 24/7 正常重启方法。

这个问题我们咨询unicorn documentation。对于正常重启(无需停机),您可以使用两种策略:

  • kill -HUP unicorn_master_pid 它要求您的应用禁用“preload_app”指令,从而增加每个 unicorn worker 的启动时间。如果你能忍受——继续,这是你的决定。
  • kill -USR2 unicorn_master_pidkill -QUIT unicorn_master_pid

  • 更复杂的方法,当您已经在处理性能问题时。基本上它会重新执行 unicorn 主进程,然后你应该杀死它的前身。理论上你可以处理 usr2-sleep-quit 方法。另一种(我可能会说是正确的)方法是使用 unicorn before_fork 钩子(Hook),它将被执行,当新的主进程将产生并会尝试为自己的新子进程。
    你可以把这样的东西放在 config/unicorn.rb 中:
    # Where to drop a pidfile
    pid project_home + '/tmp/pids/unicorn.pid'
    
    before_fork do |server, worker|
      server.logger.info("worker=#{worker.nr} spawning in #{Dir.pwd}")
    
      # graceful shutdown.
      old_pid_file = project_home + '/tmp/pids/unicorn.pid.oldbin'
      if File.exists?(old_pid_file) && server.pid != old_pid_file
        begin
          old_pid = File.read(old_pid_file).to_i
          server.logger.info("sending QUIT to #{old_pid}")
          # we're killing old unicorn master right there
          Process.kill("QUIT", old_pid)
        rescue Errno::ENOENT, Errno::ESRCH
          # someone else did our job for us
        end
      end
    end
    

    当新的 unicorn 准备好 fork worker 时,杀死旧的 unicorn 或多或少是安全的。这样你不会有任何停机时间,老 unicorn 会等待它的 worker 完成。

    还有一件事 - 你可能想把它放在 runit 或 init 监督下。这样你的 capistrano 任务就会像 sv reload unicornrestart unicorn/etc/init.d/unicorn restart 一样简单。这是好事。

    关于ruby - 使用 Capistrano 3.x 启动或重新启动 Unicorn,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19896800/

    10-15 09:13