Ruby on rails unicorn/rails的零停机重启
在部署脚本中,我们使用以下代码段重新启动unicorn:Ruby on rails unicorn/rails的零停机重启,ruby-on-rails,unicorn,Ruby On Rails,Unicorn,在部署脚本中,我们使用以下代码段重新启动unicorn: desc "Zero downtime restart of Unicorn" task :restart do run "kill -s USR2 unicorn_pid" end 主流程分叉,启动新员工,然后杀死旧员工。但现在看来,新主人在新孩子们还没有完全长大之前就杀死了旧主人并接管了所有新的关系。当我们使用preload\u app false禁用应用程序预加载时,新的工作人员大约需要30-60秒才能启动。在此期间,新连接/
desc "Zero downtime restart of Unicorn"
task :restart do
run "kill -s USR2 unicorn_pid"
end
主流程分叉,启动新员工,然后杀死旧员工。但现在看来,新主人在新孩子们还没有完全长大之前就杀死了旧主人并接管了所有新的关系。当我们使用preload\u app false
禁用应用程序预加载时,新的工作人员大约需要30-60秒才能启动。在此期间,新连接/网站将挂起。如何避免这种情况,使新的主节点只在新的子节点完全就绪并准备好处理请求时才接管
更新:
我的unicorn.rb如下所示:
# name of application
application = "myapp"
# environment specific stuff
case ENV["RAILS_ENV"]
when "integration", "staging"
worker_processes 1
when "production"
worker_processes 4
else
raise "Invalid runtime environment '#{ENV["RAILS_ENV"]}'"
end
# set directories
base_dir = "/srv/#{application}/current"
shared_path = "/srv/#{application}/shared"
working_directory base_dir
# maximum runtime of requests
timeout 300
# multiple listen directives are allowed
listen "#{shared_path}/unicorn.sock", :backlog => 64
# location of pid file
pid "#{shared_path}/pids/unicorn.pid"
# location of log files
stdout_path "#{shared_path}/log/unicorn.log"
stderr_path "#{shared_path}/log/unicorn.err"
# combine REE with "preload_app true" for memory savings
# http://rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
preload_app false
if GC.respond_to?(:copy_on_write_friendly=)
GC.copy_on_write_friendly = true
end
before_exec do |server|
# see http://unicorn.bogomips.org/Sandbox.html
ENV["BUNDLE_GEMFILE"] = "#{base_dir}/Gemfile"
end
before_fork do |server, worker|
# the following is highly recomended for "preload_app true"
if defined?(ActiveRecord::Base)
ActiveRecord::Base.connection.disconnect!
end
if defined?(Sequel::Model)
Sequel::DATABASES.each{ |db| db.disconnect }
end
# This allows a new master process to incrementally
# phase out the old master process with SIGTTOU to avoid a
# thundering herd (especially in the "preload_app false" case)
# when doing a transparent upgrade. The last worker spawned
# will then kill off the old master process with a SIGQUIT.
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
Process.kill(sig, 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|
if defined?(ActiveRecord::Base)
ActiveRecord::Base.establish_connection
end
end
我认为主要的问题是没有
child\u ready
hook。叉子前面的和钩子后面的称为“太早”。我想我可以在after\u fork
钩子中添加一些逻辑,以某种方式检测孩子什么时候准备好了……但我希望有一个更简单的解决方案:) 你能给我看一下你的独角兽配置文件吗?根据我的经验,我的老主人是不会在没有人工干预的情况下被杀死的。尝试一下HUP
支持USR2
,同时看看Unicorn的信号文档