当我使用 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
我也尝试将运行放在 :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 shell 中使用
unicorn -c /etc/unicorn/deployrails.conf.rb -D
启动 unicorn 进程。我可以使用 kill USR2 从 VM shell 终止主 Unicorn 进程,但即使该进程被终止,我也会收到错误消息。然后我可以使用
unicorn -c ...
再次启动该过程$ kill USR2 58798
bash: kill: USR2: arguments must be process or job IDs
总的来说,我对 Ruby、Rails 和 Deployment 很陌生。我有一个带有 Ubuntu、Nginx、RVM 和 Unicorn 的 VirtualBox 设置,到目前为止我很兴奋,但这个真的让我很困惑,任何建议或见解都值得赞赏。
最佳答案
不能说任何关于 capistrano 3(我使用 2)的具体内容,但我认为这可能会有所帮助: How to run shell commands on server in Capistrano v3? 。
我也可以分享一些与 unicorn 相关的经验,希望能有所帮助。
我假设您想要 24/7 正常重启方法。
这个问题我们咨询unicorn documentation。对于正常重启(无需停机),您可以使用两种策略:
kill -HUP unicorn_master_pid
它要求您的应用禁用“preload_app”指令,从而增加每个 unicorn worker 的启动时间。如果你能忍受——继续,这是你的决定。 kill -USR2 unicorn_master_pid
kill -QUIT unicorn_master_pid
更复杂的方法,当您已经在处理性能问题时。基本上它会重新执行 unicorn 主进程,然后你应该杀死它的前身。理论上你可以处理 usr2-sleep-quit 方法。另一种(我可能会说是正确的)方法是使用 unicorn before_fork 钩子(Hook),它将被执行,当新的主进程将产生并会尝试为自己的新子进程。
你可以把这样的东西放在 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
当新的 unicorn 准备好 fork worker 时,杀死旧的 unicorn 或多或少是安全的。这样你不会有任何停机时间,老 unicorn 会等待它的 worker 完成。
还有一件事 - 你可能想把它放在 runit 或 init 监督下。这样你的 capistrano 任务就会像
sv reload unicorn
、 restart unicorn
或 /etc/init.d/unicorn restart
一样简单。这是好事。关于ruby - 使用 Capistrano 3.x 启动或重新启动 Unicorn,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19896800/