使用Capistrano 3.x启动或重新启动Unicorn [英] Starting or restarting Unicorn with Capistrano 3.x

查看:104
本文介绍了使用Capistrano 3.x启动或重新启动Unicorn的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to start or restart Unicorn when I do cap production deploy with Capistrano 3.0.1. I have some examples that I got working with Capistrano 2.x using something like:

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的deploy.rb中使用run时,出现未定义的方法错误.

But when I try and use run in the deploy.rb for Capistrano 3.x I get an undefined method error.

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

Here are a couple of the things I tried:

# 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任务中

I have also tried putting the run within the :restart task

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 "cd ... " then I'll get a个错误的参数(1代表0)`.

If I use just run "cd ... " then I'll get awrong number of arguments (1 for 0)` in the local shell.

我可以从ssh'd VM Shell中使用unicorn -c /etc/unicorn/deployrails.conf.rb -D启动独角兽程序.

I can start the unicorn process with unicorn -c /etc/unicorn/deployrails.conf.rb -D from my ssh'd VM shell.

我可以使用kill USR2从VM Shell中终止主Unicorn进程,但是即使该进程被终止,我仍然会遇到错误.然后,我可以使用unicorn -c ...

I can kill the master Unicorn process from the VM shell using kill USR2, but even though the process is killed I get an error. I can then start the process again using unicorn -c ...

$ kill USR2 58798
bash: kill: USR2: arguments must be process or job IDs

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

I'm very new to Ruby, Rails and Deployment in general. I have a VirtualBox setup with Ubuntu, Nginx, RVM and Unicorn, I'm pretty excited so far, but this one is really messing with me, any advice or insight is appreciated.

推荐答案

关于Capistrano 3(我使用2),我无法说出任何具体的说法,但我认为这可能会有所帮助:

Can't say anything specific about capistrano 3(i use 2), but i think this may help: How to run shell commands on server in Capistrano v3?. Also i can share some unicorn-related experience, hope this helps.

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

I assume you want 24/7 graceful restart approach.

让我们参考 unicorn文档.对于正常重启(没有停机时间),可以使用两种策略:

Let's consult unicorn documentation for this matter. For graceful restart(without downtime) you can use two strategies:

  1. kill -HUP unicorn_master_pid它要求您的应用禁用'preload_app'指令,从而增加每个独角兽工作者的启动时间.如果您可以接受,那就继续吧!

  1. kill -HUP unicorn_master_pid It requires your app to have 'preload_app' directive disabled, increasing starting time of every one of unicorn workers. If you can live with that - go on, it's your call.

kill -USR2 unicorn_master_pid kill -QUIT unicorn_master_pid

更复杂的方法,当您已经在处理性能问题时.基本上它将重新执行独角兽主进程,然后您应该杀死它的前身.从理论上讲,您可以处理usr2-sleep-quit方法.另一种(也是正确的方法,我可能会说)是使用独角兽before_fork钩子,它将在新的主进程产生时尝试执行,并尝试为自己的新孩子创建钩子. 您可以在config/unicorn.rb中放入以下内容:

More sophisticated approach, when you're already dealing with performance concerns. Basically it will reexecute unicorn master process, then you should kill it's predecessor. Theoretically you can deal with usr2-sleep-quit approach. Another(and the right one, i may say) way is to use unicorn before_fork hook, it will be executed, when new master process will be spawned and will try to for new children for itself. You can put something like this in 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

当新的独角兽准备派遣工人时,杀死旧的独角兽或多或少是安全的.这样您就不会有任何停机时间,老独角兽会等待它的工人完成.

It's more or less safe to kill old unicorn when the new one is ready to fork workers. You won't get any downtime that way and old unicorn will wait for it's workers to finish.

还有另外一件事-您可能希望将其置于 runit 或初始化监督下.这样,您的capistrano任务将像sv reload unicornrestart unicorn/etc/init.d/unicorn restart一样简单.这是好事.

And one more thing - you may want to put it under runit or init supervision. That way your capistrano tasks will be as simple as sv reload unicorn, restart unicorn or /etc/init.d/unicorn restart. This is good thing.

这篇关于使用Capistrano 3.x启动或重新启动Unicorn的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆