我刚刚切换到在unicorn上部署我的Rails项目。在我的capistrano食谱中deploy:restart
是
task :restart, :except => { :no_release => true } do
run "cd #{shared_path}/pids && kill -s USR2 `cat unicorn.pid`"
end
但我不时发现,有时部署过程成功完成,但是虽然更新了unicorn.pid,但独角兽进程仍然存在。
例如,我在12月15日部署,并且我监视unicorn.pid
已更新,但是如果我运行ps -ef | grep unicorn
,我可以看到unicorn进程在我的时候仍然启动最后一次部署,所以它指的是导致问题的最后一个发布文件夹。
为什么?
以下是我的unicorn.rb
文件:
env = ENV["RAILS_ENV"]
case env
when 'pre', 'production'
@app_path = '/home/deployer/deploy/myproject'
end
if env == 'pre' || env == 'production'
user 'deployer', 'staff'
shared_path = "#{@app_path}/shared"
stderr_path "#{shared_path}/log/unicorn.stderr.log"
stdout_path "#{shared_path}/log/unicorn.stdout.log"
if env == 'production'
worker_processes 6
else
worker_processes 2
end
working_directory "#{@app_path}/current" # available in 0.94.0+
listen "/tmp/myproject.sock", :backlog => 64
timeout 30
pid "#{shared_path}/pids/unicorn.pid"
preload_app true
GC.respond_to?(:copy_on_write_friendly=) and
GC.copy_on_write_friendly = true
before_fork do |server, worker|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
old_pid = "#{shared_path}/pids/unicorn.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|
defined?(ActiveRecord::Base) and
ActiveRecord::Base.establish_connection
end
end
答案 0 :(得分:0)
我不确定为什么会这样,但我个人并不是在通过Capistrano部署时杀死了Unicorn PID。
相反,我通过神宝石启动独角兽,并配置神文件,以便在触摸文件时重新启动独角兽。
当我通过Capistrano部署时,我会在每次部署后触摸该文件,迫使unicorn进程重新启动
namespace :deploy do
desc "Touch restart.txt, which will restart all God processes"
task :restart do
run "touch #{ current_path }/tmp/restart.txt"
end
您还需要将此模块添加到.god文件中:
module God
module Conditions
class RestartFileTouched < PollCondition
attr_accessor :restart_file
def initialize
super
end
def process_start_time
Time.parse(`ps -o lstart -p #{self.watch.pid}`)
end
def restart_file_modification_time
File.mtime(self.restart_file)
end
def valid?
valid = true
valid &= complain("Attribute 'restart_file' must be specified", self) if self.restart_file.nil?
valid
end
def test
process_start_time < restart_file_modification_time
end
end
end
end