部署 Unicorn 重启无法加载最新代码

iamzhangdabei · 2013年03月19日 · 最后由 iamzhangdabei 回复于 2013年03月20日 · 4030 次阅读

unicorn 的配置文件为:

# Set your full path to application.
app_path=File.dirname(File.dirname(File.dirname(File.expand_path(__FILE__))))
rails_env = ENV["RAILS_ENV"] || "production"

# Set unicorn options
worker_processes 20
preload_app true
timeout 180
listen 10000, :tcp_nopush => false

# Spawn unicorn master worker for user apps (group: apps)
#user 'apps', 'apps' 

# Fill path to your app
working_directory app_path

# Should be 'production' by default, otherwise use other env 
rails_env = ENV['RAILS_ENV'] || 'production'

# Log everything to one file
stderr_path "#{app_path}/log/unicorn.log"
stdout_path "#{app_path}/log/unicorn.log"

# Set master PID location
pid "#{app_path}/tmp/pids/unicorn.pid"

if GC.respond_to?(:copy_on_write_friendly=)
  GC.copy_on_write_friendly = true
end

before_exec do |server|
  ENV["BUNDLE_GEMFILE"] = "#{app_path}/Gemfile"
end

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

直接使用

kill -USR2 `cat XX.pid`

会发现 unicorn.pid 中进程号也发生了变化。 但是新代码还是为生效。。。 还有,重启后会报奇怪的错误,比如明明存在的 partial,报 missing partial 错误。

无法重启的时候要注意看 unicorn.log 里面会有信息的

#1 楼 @huacnlee 重启后会报奇怪的错误,比如明明存在的 partial,报 missing partial 错误。直接 kill 再启动是没问题的

发出来看看

因为你用了preload_app true http://unicorn.bogomips.org/SIGNALS.html

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. When reloading the application, Gem.refresh will be called so updated code for your application can pick up newly installed RubyGems. It is not recommended that you uninstall libraries your application depends on while Unicorn is running, as respawned workers may enter a spawn loop when they fail to load an uninstalled dependency.

另外这个 unicorn reload 有点限制的,新代码如果修改了 Gemfile 之类的,只能 stop 然后 start

#5 楼 @luikore 我改 gemfile 重启没问题啊

#6 楼 @kingwkb 哦,没发现现在的 unicorn 已经能 reload gem 了...

#3 楼 @huacnlee

I, [2013-03-20T11:49:28.059789 #25639]  INFO -- : executing ["/u/apps/momo2/shared/bundle/ruby/1.8/bin/unicorn_rails", "-c", "config/unicorn/production.rb", "-E", "production", "-D"] (in /data/momo2/releases/20130320023602)
I, [2013-03-20T11:49:29.255501 #25639]  INFO -- : inherited addr=0.0.0.0:10000 fd=14
I, [2013-03-20T11:49:29.256125 #25639]  INFO -- : Refreshing Gem list
/u/apps/momo2/shared/bundle/ruby/1.8/bundler/gems/data_fabric-0f4942f06049/lib/data_fabric/version.rb:3: warning: already initialized constant STRING
I, [2013-03-20T11:49:42.465743 #25666]  INFO -- : worker=0 ready
I, [2013-03-20T11:49:42.709021 #25667]  INFO -- : worker=1 ready
I, [2013-03-20T11:49:42.912091 #25668]  INFO -- : worker=2 ready
I, [2013-03-20T11:49:43.275840 #25669]  INFO -- : worker=3 ready
I, [2013-03-20T11:49:43.506652 #25670]  INFO -- : worker=4 ready
I, [2013-03-20T11:49:43.899766 #25671]  INFO -- : worker=5 ready
I, [2013-03-20T11:49:43.934232 #19004]  INFO -- : reaped #<Process::Status: pid=19018,exited(0)> worker=5
I, [2013-03-20T11:49:44.193478 #25672]  INFO -- : worker=6 ready
I, [2013-03-20T11:49:44.236031 #19004]  INFO -- : reaped #<Process::Status: pid=19028,exited(0)> worker=15
I, [2013-03-20T11:49:44.236309 #19004]  INFO -- : reaped #<Process::Status: pid=19029,exited(0)> worker=16
I, [2013-03-20T11:49:44.354021 #25673]  INFO -- : worker=7 ready
I, [2013-03-20T11:49:44.538451 #19004]  INFO -- : reaped #<Process::Status: pid=19020,exited(0)> worker=7
I, [2013-03-20T11:49:44.538680 #19004]  INFO -- : reaped #<Process::Status: pid=19027,exited(0)> worker=14
I, [2013-03-20T11:49:44.538829 #19004]  INFO -- : reaped #<Process::Status: pid=19032,exited(0)> worker=19
I, [2013-03-20T11:49:44.579783 #25674]  INFO -- : worker=8 ready
I, [2013-03-20T11:49:44.639573 #19004]  INFO -- : reaped #<Process::Status: pid=19016,exited(0)> worker=3
I, [2013-03-20T11:49:44.639843 #19004]  INFO -- : reaped #<Process::Status: pid=19017,exited(0)> worker=4
I, [2013-03-20T11:49:44.639990 #19004]  INFO -- : reaped #<Process::Status: pid=19022,exited(0)> worker=9
I, [2013-03-20T11:49:44.740847 #19004]  INFO -- : reaped #<Process::Status: pid=19013,exited(0)> worker=0
I, [2013-03-20T11:49:44.741120 #19004]  INFO -- : reaped #<Process::Status: pid=19015,exited(0)> worker=2
I, [2013-03-20T11:49:44.741238 #19004]  INFO -- : reaped #<Process::Status: pid=19021,exited(0)> worker=8
I, [2013-03-20T11:49:44.741341 #19004]  INFO -- : reaped #<Process::Status: pid=19024,exited(0)> worker=11
I, [2013-03-20T11:49:44.741464 #19004]  INFO -- : reaped #<Process::Status: pid=19026,exited(0)> worker=13
I, [2013-03-20T11:49:44.725063 #25675]  INFO -- : worker=9 ready
I, [2013-03-20T11:49:44.842874 #19004]  INFO -- : reaped #<Process::Status: pid=19014,exited(0)> worker=1
I, [2013-03-20T11:49:44.843162 #19004]  INFO -- : reaped #<Process::Status: pid=19025,exited(0)> worker=12
I, [2013-03-20T11:49:44.843295 #19004]  INFO -- : reaped #<Process::Status: pid=19030,exited(0)> worker=17
I, [2013-03-20T11:49:44.843419 #19004]  INFO -- : reaped #<Process::Status: pid=19031,exited(0)> worker=18
I, [2013-03-20T11:49:44.944004 #19004]  INFO -- : reaped #<Process::Status: pid=19019,exited(0)> worker=6
I, [2013-03-20T11:49:44.944345 #19004]  INFO -- : reaped #<Process::Status: pid=19023,exited(0)> worker=10
I, [2013-03-20T11:49:44.944427 #19004]  INFO -- : master complete
I, [2013-03-20T11:49:45.005390 #25676]  INFO -- : worker=10 ready
I, [2013-03-20T11:49:45.134093 #25679]  INFO -- : worker=11 ready
I, [2013-03-20T11:49:45.362512 #25692]  INFO -- : worker=12 ready
I, [2013-03-20T11:49:45.503391 #25700]  INFO -- : worker=13 ready
I, [2013-03-20T11:49:45.762058 #25712]  INFO -- : worker=14 ready
I, [2013-03-20T11:49:46.006504 #25720]  INFO -- : worker=15 ready
I, [2013-03-20T11:49:46.193323 #25724]  INFO -- : worker=16 ready
I, [2013-03-20T11:49:46.351284 #25733]  INFO -- : worker=17 ready
I, [2013-03-20T11:49:46.543594 #25742]  INFO -- : worker=18 ready
I, [2013-03-20T11:49:46.634778 #25639]  INFO -- : master process ready
I, [2013-03-20T11:49:46.633641 #25743]  INFO -- : worker=19 ready

#5 楼 @luikore preload_app true 的时候是能刷新的,目前 Ruby China 就是这么配置的,每次重启都是 kill -USR2

#3 楼 @huacnlee 注意到我们的 Gemfile.lock 中 unicorn 版本是 unicorn (4.6.2) ruby-china 的版本是 4.2.1 不知道这个有没有影响。

#10 楼 @iamzhangdabei 这个我不知道,你可以试试 从 unicorn.log 里面来看,似乎是没啥问题

#11 楼 @huacnlee 还有

before_fork do |server, worker|
  ActiveRecord::Base.connection.disconnect!
end
after_fork do |server, worker|
  ActiveRecord::Base.establish_connection
end

我发现 ruby-china 的 unicorn 配置中是没有这个的。看来也是不需要了

#12 楼 @iamzhangdabei Ruby China 的 ORM 是 Mongoid ,所以 ActiveRecord 当然是不需要的

#11 楼 @huacnlee 终于找到问题了,

executing ["/u/apps/momo2/shared/bundle/ruby/1.8/bin/unicorn_rails", "-c", "config/unicorn/production.rb", "-E", "production", "-D"] (in /data/momo2/releases/20130320023602)

还是这一句,发现这个 20130320023602 是老的版本号。于是在 deploy.rb 里面强制

set :unicorn_path, "#{deploy_to}/current/config/unicorn/production.rb"

以及 unicorn.rb 里面

app_path = "/u/apps/momo2/current"

这样问题就解决了。

不过看 unicron 的日志,发现还是从老的版本代码目录里执行的 unicorn_rails 命令 ,不过由于-c 是绝对路径。所以问题还是解决了。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号