Запуск или перезапуск Unicorn с помощью Capistrano 3.икс
Я пытаюсь запустить или перезапустить Unicorn, когда я делаю cap production deploy
С Capistrano 3.0.1. У меня есть несколько примеров, которые я получил, работая с Capistrano 2.х, используя что-то вроде:
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
на deploy.rb
для Capistrano 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
я также попытался поставить запуск в: 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) ' в локальной оболочке.
я могу начать процесс единорога с unicorn -c /etc/unicorn/deployrails.conf.rb -D
из моей оболочки ssh'D VM.
я могу убить процесс master Unicorn из оболочки VM, используя kill USR2, но даже если процесс убит, я получаю ошибку. Затем я могу начать процесс снова, используя unicorn -c ...
$ kill USR2 58798
bash: kill: USR2: arguments must be process or job IDs
Я очень новичок в Ruby, Rails и развертывании в целом. У меня есть настройка VirtualBox с Ubuntu, Nginx, RVM и Unicorn, Я очень взволнован до сих пор, но это действительно возится со мной, любой совет или понимание ценятся.
4 ответов
Не могу сказать ничего конкретного о capistrano 3(я использую 2), но я думаю, что это может помочь:как запустить команды оболочки на сервере в Capistrano v3?. Также я могу поделиться опытом, связанным с единорогом, надеюсь, это поможет.
Я предполагаю, что вы хотите 24/7 перезапуска подход.
давайте советуйте единорог документации в этом отношении. Для изящного перезапуска (без простоя) вы можете использовать два стратегии:
kill -HUP unicorn_master_pid
для вашего приложения требуется отключить директиву "preload_app", увеличивая время запуска каждого из работников unicorn. Если вы можете жить с этим - продолжайте, это ваш выбор.kill -USR2 unicorn_master_pid
kill -QUIT unicorn_master_pid
более сложный подход, когда вы уже имеете дело с проблемами производительности. В основном он будет вынужден освоить процесс единорог, то вы должны убить его предшественник. Теоретически вы можете иметь дело с подходом usr2-sleep-quit. Другой (и правильный, я могу сказать) способ-использовать unicorn перед крючком, он будет выполнен, когда новый мастер-процесс будет порожден и попытается для новых детей для себя. Вы можете поместить что-то подобное в 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
более или менее безопасно убить старого единорога, когда новый готов раскошелиться на рабочих. Вы не получите никакого времени простоя таким образом, и старый единорог будет ждать, пока это рабочие заканчивать.
и еще одно - вы можете поставить его под Рунит или надзор инициализации. Таким образом, ваши задачи capistrano будут такими же простыми, как sv reload unicorn
, restart unicorn
или /etc/init.d/unicorn restart
. Это хорошо.
Я использую следующий код:
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
Я просто собираюсь бросить это в кольцо:capistrano 3 unicorn gem
однако, моя проблема с драгоценным камнем (и любой подход, не использующий init.D script), заключается в том, что теперь у вас могут быть два метода управления процессом unicorn. Один с этой задачей cap и один с init.D скрипты. Такие вещи, как Monit / God, будут запутаны, и вы можете потратить часы на отладку, почему у вас есть два процесса unicorn, пытающихся начать, а затем вы можете начать ненавидеть жизнь.
В настоящее время я использую следующее С capistrano 3 и unicorn:
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 и заявлениями before_fork и after_fork, упомянутыми @dredozubov
Примечание я назвал свой init.D / Unicorn скрипт unicorn_application_name.
новый работник, который должен убить старого. Вы можете видеть с ps aux | grep unicorn
что старого хозяина висит вокруг в течение нескольких секунд, прежде чем он исчезает.
вы можете попробовать использовать родной путь capistrano, как написано здесь:
Если preload_app: true и вам нужно capistrano для очистки вашего oldbin pid использовать:
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:legacy_restart'
end
end