使用Capistrano 3.x启动或重新启动Unicorn [英] Starting or restarting Unicorn with Capistrano 3.x
问题描述
当我使用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 a
wrong 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:
-
kill -HUP unicorn_master_pid
它要求您的应用禁用'preload_app'指令,从而增加每个独角兽工作者的启动时间.如果您可以接受,那就继续吧!
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 unicorn
,restart 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屋!