rails + unicorn 配置

1、基本配置

在配置unicorn时,分两种情况

preload_app true

preload_app false

preload_app false的情况下,unicorn的master不预加载rails app整个环境,每个worker都会执行整个rails app.

preload_app true的情况下,unicorn的master会预先加载rails app环境,而且在copy_on_write_friendly的情况下,每个worker都是从master执行写时复制的(节省资源)。

如果是prelad_app true的情况,需要在before_fork中关闭database connection;因为master不需要保持这个连接

before_fork do |server, worker|
  # the following is highly recomended for Rails + "preload_app true"
  # as there's no need for the master process to hold a connection
    defined?(ActiveRecord::Base) and
      ActiveRecord::Base.connection.disconnect!
end

但是,在after_fork后,需要为每个worker都重新连接上 database connection;

after_fork do |server, worker|

  # the following is *required* for Rails + "preload_app true",
  defined?(ActiveRecord::Base) and 
    ActiveRecord::Base.establish_connection
end

当有其他的socket连接时,同样需要在after_fork中,重新连接,或者在before_fork中先关闭,然后在after_fork中重新连接。


2、unicorn信号

kill -s HUP pid

当preload_app false 时,会重新加载配置和rails app,所有修改过的代码都会被重新加载,因为是每个worker去重新执行

当preload_app true 时, 会重新加载配置,但不会重新加载rails app,因为每个worker都是从master copy的,因此修改的代码也不会被重新加载

这时,需要如下命令

kill -s USR2 pid

并且在before_fork中自动关闭旧的unicorn进程

before_fork do |server, worker|
  # 在执行 kill -s USR2 `oldpid`时会执行,因为unicorn将原来的pid文件名增加了.oldbin后缀
  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
      puts "Send 'QUIT' signal to unicorn error!"      
    end 
  end 

end

结果会重新执行unicorn,生成新的进程,并关闭旧的进程

posted @ 2012-06-26 14:10  kamechen  阅读(1255)  评论(1编辑  收藏  举报