目前我的独角兽大师需要在每次部署前手动杀死
Currently my unicorn master needs to be killed manually before each deployment
我在我的 rails4 应用程序中使用 capistrano,每次我发布新版本时 (=> cap production deploy
) 我需要杀死服务器上的独角兽大师,这样 capistrano 就可以在没有任何东西的情况下行走失败。
### How can I automate the process of killing the unicorn process?
This is how my deploy.rb is looking like:
lock '3.4.0'
set :application, 'maalify'
set :repo_url, 'git@github.com:iNeedCode/Maalify.git'
set :deploy_to, '/opt/www/maalify'
set :user, 'root'
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets}
set :rbenv_ruby, '2.2.1'
set :rbenv_type, :user
set :rbenv_path, "~/.rbenv"
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w(rake gem bundle ruby rails)
set :rbenv_roles, :all
set :linked_files, %w{config/database.yml .rbenv-vars} # create these files manually ones on the server
# Capristrano3 unicorn
set :unicorn_pid, "/opt/www/maalify/current/shared/tmp/pids/unicorn.pid"
set :unicorn_config_path, "/opt/www/maalify/current/config/unicorn.rb"
# Clean up all older releases
before :deploy, "unicorn:stop"
after "deploy:publishing", "unicorn:start"
after "deploy:restart", "deploy:cleanup"
namespace :deploy do
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
execute :rake, 'cache:clear'
end
end
end
更新
这是Unicorn.rb
# set path to application
app_dir = "/opt/www/maalify"
shared_dir = "#{app_dir}/shared"
working_directory "#{app_dir}/current"
# Set unicorn options
worker_processes 1
preload_app true
timeout 30
# Set up socket location
listen "#{shared_dir}/tmp/sockets/unicorn.sock", :backlog => 64
# Logging
stderr_path "#{shared_dir}/log/unicorn.stderr.log"
stdout_path "#{shared_dir}/log/unicorn.stdout.log"
# Set master PID location
pid "#{shared_dir}/tmp/pids/unicorn.pid"
添加 before_fork
后,我仍然遇到与之前没有手动杀死独角兽时相同的错误:
/opt/www/maalify/shared/bundle/ruby/2.2.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:206:in `pid=': Already running on PID:16268 (or pid=/opt/www/maalify/shared/tmp/pids/unicorn.pid is stale) (ArgumentError)
from /opt/www/maalify/shared/bundle/ruby/2.2.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:135:in `start'
from /opt/www/maalify/shared/bundle/ruby/2.2.0/gems/unicorn-4.8.3/bin/unicorn:126:in `<top (required)>'
from /opt/www/maalify/shared/bundle/ruby/2.2.0/bin/unicorn:23:in `load'
from /opt/www/maalify/shared/bundle/ruby/2.2.0/bin/unicorn:23:in `<main>'
我在你的独角兽配置文件中注意到下一个指令:
preload_app true
这是来自 docs 的信息:
HUP - reloads config file and gracefully restart all workers. If the
"preload_app" directive is false (the default), then workers will also
pick up any application code changes when restarted. If "preload_app"
is true, then application code changes will have no effect; USR2 +
QUIT (see below) must be used to load newer code in this case.
您可以将指令 preload_app
设置为 false,然后如果您需要重新加载代码,请向主进程发送 HUP
信号。
但这是另一种无需停机即可重新加载代码的方法。您需要在配置中实现 USR2 + QUIT
方法。这意味着当您发送 USR2
信号时,独角兽会启动新的应用程序实例而不会杀死旧实例。您可以挂钩 before_fork
回调,它将为您轻松杀死旧实例。
这是示例,将其添加到独角兽配置中:
before_fork do |server, worker|
ActiveRecord::Base.connection.disconnect!
old_pid = "#{server.config[:pid]}.oldbin"
if File.exists?(old_pid) && server.pid != old_pid
begin
Process.kill("QUIT", File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
end
after_fork do |server, worker|
ActiveRecord::Base.establish_connection
end
现在发送 USR2 信号给 master 进程并检查它!
下一步是改变您的 deploy.rb。您需要删除所有 unicorn
个挂钩并添加下一个:
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:legacy_restart'
end
end
最后一步:修复 deploy.rb.
中的 pid 路径
set :unicorn_pid, "/opt/www/maalify**/current/shared/**tmp/pids/unicorn.pid"
必须是:
set :unicorn_pid, "/opt/www/maalify/shared/tmp/pids/unicorn.pid"
我在我的 rails4 应用程序中使用 capistrano,每次我发布新版本时 (=> cap production deploy
) 我需要杀死服务器上的独角兽大师,这样 capistrano 就可以在没有任何东西的情况下行走失败。
### How can I automate the process of killing the unicorn process?
This is how my deploy.rb is looking like:
lock '3.4.0'
set :application, 'maalify'
set :repo_url, 'git@github.com:iNeedCode/Maalify.git'
set :deploy_to, '/opt/www/maalify'
set :user, 'root'
set :linked_dirs, %w{log tmp/pids tmp/cache tmp/sockets}
set :rbenv_ruby, '2.2.1'
set :rbenv_type, :user
set :rbenv_path, "~/.rbenv"
set :rbenv_prefix, "RBENV_ROOT=#{fetch(:rbenv_path)} RBENV_VERSION=#{fetch(:rbenv_ruby)} #{fetch(:rbenv_path)}/bin/rbenv exec"
set :rbenv_map_bins, %w(rake gem bundle ruby rails)
set :rbenv_roles, :all
set :linked_files, %w{config/database.yml .rbenv-vars} # create these files manually ones on the server
# Capristrano3 unicorn
set :unicorn_pid, "/opt/www/maalify/current/shared/tmp/pids/unicorn.pid"
set :unicorn_config_path, "/opt/www/maalify/current/config/unicorn.rb"
# Clean up all older releases
before :deploy, "unicorn:stop"
after "deploy:publishing", "unicorn:start"
after "deploy:restart", "deploy:cleanup"
namespace :deploy do
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
execute :rake, 'cache:clear'
end
end
end
更新
这是Unicorn.rb
# set path to application
app_dir = "/opt/www/maalify"
shared_dir = "#{app_dir}/shared"
working_directory "#{app_dir}/current"
# Set unicorn options
worker_processes 1
preload_app true
timeout 30
# Set up socket location
listen "#{shared_dir}/tmp/sockets/unicorn.sock", :backlog => 64
# Logging
stderr_path "#{shared_dir}/log/unicorn.stderr.log"
stdout_path "#{shared_dir}/log/unicorn.stdout.log"
# Set master PID location
pid "#{shared_dir}/tmp/pids/unicorn.pid"
添加 before_fork
后,我仍然遇到与之前没有手动杀死独角兽时相同的错误:
/opt/www/maalify/shared/bundle/ruby/2.2.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:206:in `pid=': Already running on PID:16268 (or pid=/opt/www/maalify/shared/tmp/pids/unicorn.pid is stale) (ArgumentError)
from /opt/www/maalify/shared/bundle/ruby/2.2.0/gems/unicorn-4.8.3/lib/unicorn/http_server.rb:135:in `start'
from /opt/www/maalify/shared/bundle/ruby/2.2.0/gems/unicorn-4.8.3/bin/unicorn:126:in `<top (required)>'
from /opt/www/maalify/shared/bundle/ruby/2.2.0/bin/unicorn:23:in `load'
from /opt/www/maalify/shared/bundle/ruby/2.2.0/bin/unicorn:23:in `<main>'
我在你的独角兽配置文件中注意到下一个指令:
preload_app true
这是来自 docs 的信息:
HUP - reloads config file and gracefully restart all workers. If the "preload_app" directive is false (the default), then workers will also pick up any application code changes when restarted. If "preload_app" is true, then application code changes will have no effect; USR2 + QUIT (see below) must be used to load newer code in this case.
您可以将指令 preload_app
设置为 false,然后如果您需要重新加载代码,请向主进程发送 HUP
信号。
但这是另一种无需停机即可重新加载代码的方法。您需要在配置中实现 USR2 + QUIT
方法。这意味着当您发送 USR2
信号时,独角兽会启动新的应用程序实例而不会杀死旧实例。您可以挂钩 before_fork
回调,它将为您轻松杀死旧实例。
这是示例,将其添加到独角兽配置中:
before_fork do |server, worker|
ActiveRecord::Base.connection.disconnect!
old_pid = "#{server.config[:pid]}.oldbin"
if File.exists?(old_pid) && server.pid != old_pid
begin
Process.kill("QUIT", File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
end
after_fork do |server, worker|
ActiveRecord::Base.establish_connection
end
现在发送 USR2 信号给 master 进程并检查它!
下一步是改变您的 deploy.rb。您需要删除所有 unicorn
个挂钩并添加下一个:
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
task :restart do
invoke 'unicorn:legacy_restart'
end
end
最后一步:修复 deploy.rb.
中的 pid 路径set :unicorn_pid, "/opt/www/maalify**/current/shared/**tmp/pids/unicorn.pid"
必须是:
set :unicorn_pid, "/opt/www/maalify/shared/tmp/pids/unicorn.pid"