使用Capistrano 3.x启动或重启Unicorn

kap*_*lan 12 ruby nginx unicorn capistrano3

当我cap production deploy使用Capistrano 3.0.1 时,我正在尝试启动或重启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
Run Code Online (Sandbox Code Playgroud)

但是当我尝试rundeploy.rbCapistrano 3.x中使用时,我得到一个未定义的方法错误.

以下是我尝试过的几件事:

# 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
Run Code Online (Sandbox Code Playgroud)

我也试过把run放在: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    
Run Code Online (Sandbox Code Playgroud)

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

我可以unicorn -c /etc/unicorn/deployrails.conf.rb -D从我的ssh'd VM shell 启动unicorn进程.

我可以使用kill USR2从VM shell中杀死主Unicorn进程,但即使进程被终止,我也会收到错误.然后我可以再次启动该过程unicorn -c ...

$ kill USR2 58798
bash: kill: USR2: arguments must be process or job IDs
Run Code Online (Sandbox Code Playgroud)

我对Ruby,Rails和部署一般都很陌生.我有一个使用Ubuntu,Nginx,RVM和Unicorn的VirtualBox设置,到目前为止我非常兴奋,但是这个真的很烦我,任何建议或见解都值得赞赏.

Ale*_*sev 13

我正在使用以下代码:

namespace :unicorn do
  desc 'Stop Unicorn'
  task :stop do
    on roles(:app) do
      if test("[ -f #{fetch(:unicorn_pid)} ]")
        execute :kill, capture(:cat, fetch(:unicorn_pid))
      end
    end
  end

  desc 'Start Unicorn'
  task :start do
    on roles(:app) do
      within current_path do
        with rails_env: fetch(:rails_env) do
          execute :bundle, "exec unicorn -c #{fetch(:unicorn_config)} -D"
        end
      end
    end
  end

  desc 'Reload Unicorn without killing master process'
  task :reload do
    on roles(:app) do
      if test("[ -f #{fetch(:unicorn_pid)} ]")
        execute :kill, '-s USR2', capture(:cat, fetch(:unicorn_pid))
      else
        error 'Unicorn process not running'
      end
    end
  end

  desc 'Restart Unicorn'
  task :restart
  before :restart, :stop
  before :restart, :start
end
Run Code Online (Sandbox Code Playgroud)


dre*_*bov 6

不能说具体的capistrano 3(我使用2),但我认为这可能会有所帮助:如何在Capistrano v3的服务器上运行shell命令?.我也可以分享一些与独角兽相关的经历,希望这会有所帮助.

我假设你想要24/7优雅重启方法.

我们来咨询unicorn文档.为了优雅重启(无停机时间),您可以使用两种策略:

  1. kill -HUP unicorn_master_pid它要求您的应用禁用'preload_app'指令,增加每个独角兽工作人员的开始时间.如果你可以忍受 - 继续,这是你的电话.

  2. kill -USR2 unicorn_master_pid kill -QUIT unicorn_master_pid

当您处理性能问题时,更复杂的方法.基本上它会重新执行独角兽主进程,那么你应该杀死它的前身.从理论上讲,你可以处理usr2-sleep-quit方法.另一个(也是正确的,我可能会说)方式是使用unicorn before_fork钩子,它将被执行,当新的主进程将被生成并将尝试为自己的新子进程.你可以在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
Run Code Online (Sandbox Code Playgroud)

当新的独角兽准备分叉工人时,杀死旧独角兽或多或少都是安全的.你不会那样得到任何停机时间,老独角兽会等待它的工人完成.

还有一件事 - 你可能想把它置于runit或init监督之下.这样你的capistrano任务将如此简单sv reload unicorn,restart unicorn/etc/init.d/unicorn restart.这是好事.