我在使用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
我也尝试将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
如果我在本地shell中只使用run "cd ... " then I'll get a
个错误数量的参数(1表示0)`。
我可以从我的ssh&#VM VM shell中使用unicorn -c /etc/unicorn/deployrails.conf.rb -D
启动独角兽进程。
我可以使用kill USR2从VM shell中杀死主Unicorn进程,但即使进程被终止,我也会收到错误。然后,我可以使用unicorn -c ...
$ kill USR2 58798
bash: kill: USR2: arguments must be process or job IDs
我对Ruby,Rails和部署一般都很陌生。我有一个使用Ubuntu,Nginx,RVM和Unicorn的VirtualBox设置,到目前为止我非常兴奋,但是这个真的很烦我,任何建议或见解都值得赞赏。
答案 0 :(得分: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
答案 1 :(得分:6)
不能说有关capistrano 3的任何具体内容(我使用2),但我认为这可能有所帮助:How to run shell commands on server in Capistrano v3?。 此外,我可以分享一些与独角兽相关的经历,希望这会有所帮助。
我假设你想要24/7优雅的重启方法。
让我们就此问题咨询unicorn documentation。为了优雅重启(无停机时间),您可以使用两种策略:
kill -HUP unicorn_master_pid
它要求您的应用禁用'preload_app'指令,增加每个独角兽工作人员的开始时间。如果你可以忍受 - 继续,这是你的电话。
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
当新的独角兽准备分叉工人时,杀死旧独角兽或多或少是安全的。你不会那样得到任何停机时间,老独角兽会等待它的工人完成。
还有一件事 - 您可能希望将其置于runit或初始监督之下。这样,您的capistrano任务就像sv reload unicorn
,restart unicorn
或/etc/init.d/unicorn restart
一样简单。这是好事。
答案 2 :(得分:4)
我要把它扔进戒指:capistrano 3 unicorn gem
但是,我对gem的问题(以及任何不使用init.d脚本的方法)是,您现在可以使用两种方法来管理您的独角兽进程。一个有这个cap任务,一个有init.d脚本。像Monit / God这样的事情会让人感到困惑,你可能会花几个小时调试为什么你有两个独角兽进程试图开始,然后你可能会开始讨厌生活。
目前我在capistrano 3和独角兽中使用以下内容:
namespace :unicorn do
desc 'Restart application'
task :restart do
on roles(:app) do
puts "restarting unicorn..."
execute "sudo /etc/init.d/unicorn_#{fetch(:application)} restart"
sleep 5
puts "whats running now, eh unicorn?"
execute "ps aux | grep unicorn"
end
end
end
以上内容与preload_app:true以及@dredozubov提到的before_fork和after_fork语句相结合
注意我已将init.d / unicorn脚本命名为unicorn_application_name。
启动的新工人应该杀掉旧工人。您可以看到ps aux | grep unicorn
旧主人在它消失之前会挂起几秒钟。
答案 3 :(得分:0)
您可以尝试使用原始的capistrano方式编写here:
如果preload_app:true,你需要使用capistrano清理你的oldbin pid:
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:legacy_restart'
end
end
答案 4 :(得分:0)
要查看所有大写字母:
cap -T
它显示:
***
cap unicorn:add_worker # Add a worker (TTIN)
cap unicorn:duplicate # Duplicate Unicorn; alias of unicorn:re...
cap unicorn:legacy_restart # Legacy Restart (USR2 + QUIT); use this...
cap unicorn:reload # Reload Unicorn (HUP); use this when pr...
cap unicorn:remove_worker # Remove a worker (TTOU)
cap unicorn:restart # Restart Unicorn (USR2); use this when ...
cap unicorn:start # Start Unicorn
cap unicorn:stop # Stop Unicorn (QUIT)
***
因此,要开始生产独角兽:
cap production unicorn:start
然后重新启动:
cap production unicorn:restart
PS不要忘记正确使用 gem capistrano3-unicorn