unicorn を Server::Starter 経由でhot deployを実現する
上記の記事を参考にServer::Starter 経由でhot deployに対応したのでその記録です。
内容
Server::Starter
をinstall
$ brew install cpanminus $ sudo cpanm Server::Starter $ ↪ cpanm Server::Starter Server::Starter is up to date. (0.35) $ perldoc -l Server::Starter /usr/local/Cellar/perl/5.30.0/lib/perl5/site_perl/5.30.0/Server/Starter.pm $ ↪ /usr/local/Cellar/perl/5.30.0/bin/start_server server program not specified
Hello World!
を返却するシンプルなアプリケーションファイルを記述。
- config.ru
require 'rubygems' require 'sinatra/base' #worker_processes 2 class HelloApp < Sinatra::Base get '/' do 'Hello World!' end end run HelloApp
- config/unicorn.conf
# frozen_string_literal: true worker_processes 8 timeout 30 preload_app true current_dir = "./simple-unicorn" working_directory current_dir listen "#{current_dir}/tmp/sockets/unicorn.sock", backlog: 2048 if ENV.key?('SERVER_STARTER_PORT') fds = ENV['SERVER_STARTER_PORT'].split(';').map do |x| _path_or_port, fd = x.split('=', 2) fd end ENV['UNICORN_FD'] = fds.join(',') ENV.delete('SERVER_STARTER_PORT') end before_fork do |server, worker| $stdout.puts "before fork" # Throttle the master from forking too quickly by sleeping. Due # to the implementation of standard Unix signal handlers, this # helps (but does not completely) prevent identical, repeated signals # from being lost when the receiving process is busy. sleep 1 end status_file = "#{current_dir}/server.status" after_fork do |server, worker| $stdout.puts "after fork" pids = File.readlines(status_file).map { |line| line.chomp.split(':') }.to_h old_gen = ENV['SERVER_STARTER_GENERATION'].to_i - 1 if old_pid = pids[old_gen.to_s] begin sig = ((worker.nr + 1) >= server.worker_processes) ? :QUIT : :TTOU $stdout.puts "sig: #{sig}, old_pid.to_i: #{old_pid.to_i}" Process.kill(sig, old_pid.to_i) rescue Errno::ENOENT, Errno::ESRCH # rubocop:disable Lint/HandleExceptions end else $stdout.puts "not condition(old_pid = pids[old_gen.to_s]): #{old_pid = pids[old_gen.to_s]}" end end before_exec do |_| ENV['BUNDLE_GEMFILE'] = "#{current_dir}/Gemfile" end
Server::Starter 経由でunicornの起動
↪ /usr/local/Cellar/perl/5.30.0/bin/start_server --path=/simple-unicorn/tmp/sockets/unicorn.sock --signal-on-term=QUIT --signal-on-hup=QUIT --status-file=/simple-unicorn/server.status --pid-file=/simple-unicorn/tmp/pids/unicorn.pid --kill-old-delay=5 -- bundle exec --keep-file-descriptors unicorn -c config/unicorn.conf config.ru start_server (pid:61975) starting now... starting new worker 61977 I, [2020-12-24T09:10:31.291689 #61977] INFO -- : inherited addr=/simple-unicorn/tmp/sockets/unicorn.sock fd=4 I, [2020-12-24T09:10:31.291816 #61977] INFO -- : Refreshing Gem list
unicornのpidを確認
↪ ps aux | grep unicorn <user> 62057 0.0 0.0 4278320 872 s012 S+ 9:10AM 0:00.00 grep --color=auto unicorn <user> 62055 0.0 0.0 4364876 2080 s011 S+ 9:10AM 0:00.00 unicorn worker[7] -c config/unicorn.conf config.ru <user> 62054 0.0 0.0 4364876 2004 s011 S+ 9:10AM 0:00.00 unicorn worker[6] -c config/unicorn.conf config.ru <user> 62051 0.0 0.0 4364876 2080 s011 S+ 9:10AM 0:00.00 unicorn worker[5] -c config/unicorn.conf config.ru <user> 62043 0.0 0.0 4364876 2020 s011 S+ 9:10AM 0:00.00 unicorn worker[4] -c config/unicorn.conf config.ru <user> 62036 0.0 0.0 4364876 2132 s011 S+ 9:10AM 0:00.00 unicorn worker[3] -c config/unicorn.conf config.ru <user> 62026 0.0 0.0 4373068 2144 s011 S+ 9:10AM 0:00.00 unicorn worker[2] -c config/unicorn.conf config.ru <user> 62009 0.0 0.0 4364876 2144 s011 S+ 9:10AM 0:00.00 unicorn worker[1] -c config/unicorn.conf config.ru <user> 61991 0.0 0.0 4364876 2176 s011 S+ 9:10AM 0:00.00 unicorn worker[0] -c config/unicorn.conf config.ru <user> 61977 0.0 0.1 4365132 24988 s011 S+ 9:10AM 0:00.45 unicorn master -c config/unicorn.conf config.ru <user> 61975 0.0 0.1 4327700 11608 s011 S+ 9:10AM 0:00.08 /usr/local/Cellar/perl/5.30.0/bin/start_server --path=/simple-unicorn/tmp/sockets/unicorn.sock --signal-on-term=QUIT --signal-on-hup=QUIT --status-file=/simple-unicorn/server.status --pid-file=/simple-unicorn/tmp/pids/unicorn.pid --kill-old-delay=5 -- bundle exec --keep-file-descriptors unicorn -c config/unicorn.conf config.ru
worker_processes
が8なのを確認できるので、Server::Starter
にHUPシグナルを送信しhot deployを行う。
$ kill -HUP 61975
プロセスを確認。
↪ ps aux | grep unicorn <user> 62346 0.0 0.0 4293680 864 s012 S+ 9:15AM 0:00.00 grep --color=auto unicorn <user> 62344 0.0 0.0 4380236 2384 s011 S+ 9:15AM 0:00.00 unicorn worker[1] -c config/unicorn.conf config.ru <user> 62340 0.0 0.0 4380236 2268 s011 S+ 9:15AM 0:00.00 unicorn worker[0] -c config/unicorn.conf config.ru <user> 62331 0.0 0.2 4380492 25348 s011 S+ 9:15AM 0:00.36 /usr/local/bin/unicorn -c config/unicorn.conf config.ru <user> 62051 0.0 0.0 4364876 2124 s011 S+ 9:10AM 0:00.01 unicorn worker[5] -c config/unicorn.conf config.ru <user> 62043 0.0 0.0 4364876 2080 s011 S+ 9:10AM 0:00.01 unicorn worker[4] -c config/unicorn.conf config.ru <user> 62036 0.0 0.0 4364876 2172 s011 S+ 9:10AM 0:00.01 unicorn worker[3] -c config/unicorn.conf config.ru <user> 62026 0.0 0.0 4373068 2220 s011 S+ 9:10AM 0:00.00 unicorn worker[2] -c config/unicorn.conf config.ru <user> 62009 0.0 0.0 4364876 2184 s011 S+ 9:10AM 0:00.00 unicorn worker[1] -c config/unicorn.conf config.ru <user> 61991 0.0 0.0 4364876 2188 s011 S+ 9:10AM 0:00.00 unicorn worker[0] -c config/unicorn.conf config.ru <user> 61977 0.0 0.1 4365132 24996 s011 S+ 9:10AM 0:00.45 unicorn master -c config/unicorn.conf config.ru <user> 61975 0.0 0.1 4327700 11616 s011 S+ 9:10AM 0:00.08 /usr/local/Cellar/perl/5.30.0/bin/start_server --path=/simple-unicorn/tmp/sockets/unicorn.sock --signal-on-term=QUIT --signal-on-hup=QUIT --status-file=/simple-unicorn/server.status --pid-file=/simple-unicorn/tmp/pids/unicorn.pid --kill-old-delay=5 -- bundle exec --keep-file-descriptors unicorn -c config/unicorn.conf config.ru
プロセスを確認し新規worker(62344
や62340
)が立ち上がっていることが確認できる。
この状態で、status fileも確認すると古い世代とmaster、新しい世代とmasterの両方を確認。
↪ cat /simple-unicorn/server.status 1:61977 2:62331
↪ ps aux | grep unicorn <user> 62363 0.0 0.0 4287536 884 s012 S+ 9:15AM 0:00.00 grep --color=auto unicorn <user> 62360 0.0 0.0 4380236 2208 s011 S+ 9:15AM 0:00.00 unicorn worker[7] -c config/unicorn.conf config.ru <user> 62359 0.0 0.0 4380236 2412 s011 S+ 9:15AM 0:00.00 unicorn worker[6] -c config/unicorn.conf config.ru <user> 62358 0.0 0.0 4380236 2260 s011 S+ 9:15AM 0:00.00 unicorn worker[5] -c config/unicorn.conf config.ru <user> 62357 0.0 0.0 4380236 2400 s011 S+ 9:15AM 0:00.00 unicorn worker[4] -c config/unicorn.conf config.ru <user> 62351 0.0 0.0 4380236 2364 s011 S+ 9:15AM 0:00.00 unicorn worker[3] -c config/unicorn.conf config.ru <user> 62350 0.0 0.0 4380236 2440 s011 S+ 9:15AM 0:00.00 unicorn worker[2] -c config/unicorn.conf config.ru <user> 62344 0.0 0.0 4380236 2412 s011 S+ 9:15AM 0:00.00 unicorn worker[1] -c config/unicorn.conf config.ru <user> 62340 0.0 0.0 4380236 2268 s011 S+ 9:15AM 0:00.00 unicorn worker[0] -c config/unicorn.conf config.ru <user> 62331 0.0 0.2 4380492 25348 s011 S+ 9:15AM 0:00.37 unicorn master -c config/unicorn.conf config.ru <user> 61975 0.0 0.1 4327700 11616 s011 S+ 9:10AM 0:00.08 /usr/local/Cellar/perl/5.30.0/bin/start_server --path=/simple-unicorn/tmp/sockets/unicorn.sock --signal-on-term=QUIT --signal-on-hup=QUIT --status-file=/simple-unicorn/server.status --pid-file=/simple-unicorn/tmp/pids/unicorn.pid --kill-old-delay=5 -- bundle exec --keep-file-descriptors unicorn -c config/unicorn.conf config.ru
時間が経経過し、masterのpidが 61975
から 62331
に代わり入れ替わっていることが確認できる。
statusファイルも次世代と新規masterに更新されていることも確認できた。
↪ cat /simple-unicorn/server.status 2:62331
おわり。