独角兽& Rails&主管+ Capistrano部署:优雅地停止和启动独角兽

时间:2017-07-18 10:24:47

标签: ruby-on-rails capistrano unicorn restart

由于意外的独角兽要求,这让我无法忍受痛苦,所以我想我会把解决方案留给其他人:

我正在跑步 - Ruby 2.3.1 - Ubuntu 16.04 - Unicorn 5.3.0 - 主管

我遇到的主要问题是优雅重启。我将以下内容发送给主管流程:

supervisorctl signal USR2 unicorn

Unicorn会处理信号,并正常重启。但是 - 每隔一段时间,开发人员就会抱怨他们的代码没有加载,而且不经常,整个重启过程都会失败。

发生的事情是Unicorn在发出信号时没有尊重working_directory,而是试图从之前的符号链接重新加载。尽管unicorn配置中的工作目录设置为/ path / to / app / current而不是底层/ path / to / release /目录。

Unicorn将从之前部署的应用程序重新启动工作程序,并且当初始版本目录从系统中清除时(即capistrano被设置为保留X版本),该过程将失败,因为发布目录独角兽最初是在将从系统中删除。

关键是在unicorn.conf.rb文件中添加以下内容:

Unicorn::HttpServer::START_CTX[:cwd] = "/path/to/current"
Unicorn::HttpServer::START_CTX[0] = "/path/to/your/unicorn-rails/binary"

并且还明确定义bundle gemfile路径(因为加载时的unicorn将其设置为初始版本目录,并再次忽略/ path / to / current)。

before_exec do |server|
  ENV['BUNDLE_GEMFILE'] = "/path/to/current/Gemfile"
end

我在下面发布了我的整个配置:

# Unicorn supervisor config
[program:unicorn]
command=/bin/start_unicorn.sh 
stdout_logfile=/var/log/supervisor/program_supervise_unicorn.log
stderr_logfile=/var/log/supervisor/program_supervise_unicorn.error
priority=100
user=web_user
directory=/srv/applications/ewok/current
autostart=true
autorestart=true
stopsignal=QUIT


#Unicorn start script (start_unicorn.sh)
!/bin/bash
source /etc/profile
cd /srv/applications/ewok/current
exec bundle exec unicornherder -u unicorn_rails -p 
/srv/applications/ewok/shared/pids/unicorn.pid -- -c config/unicorn.conf.rb -E $RAILS_ENV
exit 0 


# My unicorn.conf.rb
APP_PATH = "/srv/applications/ewok/current"
SHARED_PATH = "/srv/applications/ewok/shared"

Unicorn::HttpServer::START_CTX[:cwd] = APP_PATH
Unicorn::HttpServer::START_CTX[0] = "/usr/local/rvm/gems/ruby-2.3.1@ewok/bin/unicorn_rails"

worker_processes 3
working_directory APP_PATH
listen "unix:#{SHARED_PATH}/pids/.unicorn.sock", :backlog => 64
listen 8080, :tcp_nopush => true
timeout 30
pid "#{SHARED_PATH}/pids/unicorn.pid"
old_pid ="#{SHARED_PATH}/pids/unicorn.pid.oldbin"
stderr_path "#{SHARED_PATH}/log/unicorn.stderr.log"
stdout_path "#{SHARED_PATH}/log/unicorn.stdout.log"
preload_app true

GC.respond_to?(:copy_on_write_friendly=) and
GC.copy_on_write_friendly = true

#check_client_connection false
run_once = true

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

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and 
ActiveRecord::Base.connection.disconnect!
  run_once = false if run_once # prevent from firing again

  # Before forking, kill the master process that belongs to the .oldbin 
PID.
  # This enables 0 downtime deploys.
  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

希望这对某人有所帮助,因为在我修复它之前,我正要开始考虑猴子修补独角兽。

0 个答案:

没有答案