나는 어플을 unicorn
으로 실행하는 데 사용하는 runit
서비스를 보유하고 있습니다.runit 서비스가 즉시 다시 시작될 수 있습니까?
재시작 명령은 신호 (USR2)를 사용하여 가동 중지 시간 제로 재시작을 처리합니다. 기본적으로 이전 프로세스가 종료되기 전에 새 프로세스가 준비 될 때까지 대기합니다.
이렇게하면 service myservice restart
이 끝날 때까지 돌아 오지 않는 매우 긴 (40 초) 재시작 시간이 발생합니다.
runit에 더 긴 타임 아웃 (나는 이미하고있다.)을 줄 수 있지만, 나는 이것을 재발동 시켜서 즉시 반환 할 것이다. (또는 USR2 신호가 발사 된 후에도 .가 완료 될 때까지 기다리지 않고
전체 논리는 unicorn
다시 시작과 제로 다운 타임에 대한 여러 블로그 게시물에서 rails
배포를 가져온 것입니다
- https://gist.github.com/czarneckid/4639793
- https://gist.github.com/JeanMertz/8996796
- https://nulogy.com/who-we-are/company-blog/articles/zero-downtime-deployments-with-chef-nginx-and-unicorn/
이이 (요리사에 의해 생성)을 runit
스크립트입니다 : 이것은 Runit를 사용하는 슈퍼 이상한 방법입니다
#!/bin/bash
#
# This file is managed by Chef, using the <%= node.name %> cookbook.
# Editing this file by hand is highly discouraged!
#
exec 2>&1
#
# Since unicorn creates a new pid on restart/reload, it needs a little extra
# love to manage with runit. Instead of managing unicorn directly, we simply
# trap signal calls to the service and redirect them to unicorn directly.
#
RUNIT_PID=$$
APPLICATION_NAME=<%= @options[:application_name] %>
APPLICATION_PATH=<%= File.join(@options[:path], 'current') %>
BUNDLE_CMD="<%= @options[:bundle_command] ? "#{@options[:bundle_command]} exec" : '' %>"
UNICORN_CMD=<%= @options[:unicorn_command] ? @options[:unicorn_command] : 'unicorn' %>
UNICORN_CONF=<%= @options[:unicorn_config_path] ? @options[:unicorn_config_path] : File.join(@options[:path], 'current', 'config', 'unicorn.rb') %>
RAILS_ENV=<%= @options[:rails_env] %>
CUR_PID_FILE=<%= @options['pid'] ? @options['pid'] : File.join(@options[:path], 'current', 'shared', 'pids', "#{@options[:application_name]}.pid") %>
ENV_PATH=<%= @options[:env_dir] %>
OLD_PID_FILE=$CUR_PID_FILE.oldbin
echo "Runit service restarted (PID: $RUNIT_PID)"
function is_unicorn_alive {
set +e
if [ -n $1 ] && kill -0 $1 >/dev/null 2>&1; then
echo "yes"
fi
set -e
}
if [ -e $OLD_PID_FILE ]; then
OLD_PID=$(cat $OLD_PID_FILE)
echo "Old master detected (PID: $OLD_PID), waiting for it to quit"
while [ -n "$(is_unicorn_alive $OLD_PID)" ]; do
sleep 5
done
fi
if [ -e $CUR_PID_FILE ]; then
CUR_PID=$(cat $CUR_PID_FILE)
if [ -n "$(is_unicorn_alive $CUR_PID)" ]; then
echo "Detected running Unicorn instance (PID: $CUR_PID)"
RUNNING=true
fi
fi
function start {
unset ACTION
if [ $RUNNING ]; then
restart
else
echo 'Starting new unicorn instance'
cd $APPLICATION_PATH
exec chpst -e $ENV_PATH $BUNDLE_CMD $UNICORN_CMD -c $UNICORN_CONF -E $RAILS_ENV
sleep 3
CUR_PID=$(cat $CUR_PID_FILE)
fi
}
function stop {
unset ACTION
echo 'Initializing graceful shutdown'
kill -QUIT $CUR_PID
while [ -n "$(is_unicorn_alive $CUR_PID)" ]; do
echo '.'
sleep 2
done
echo 'Unicorn stopped, exiting Runit process'
kill -9 $RUNIT_PID
}
function restart {
unset ACTION
echo "Restart request captured, swapping old master (PID: $CUR_PID) for new master with USR2"
kill -USR2 $CUR_PID
sleep 2
echo 'Restarting Runit service to capture new master PID'
exit
}
function alarm {
unset ACTION
echo 'Unicorn process interrupted'
}
trap 'ACTION=stop' STOP TERM KILL
trap 'ACTION=restart' QUIT USR2 INT
trap 'ACTION=alarm' ALRM
[ $RUNNING ] || ACTION=start
if [ $ACTION ]; then
echo "Performing \"$ACTION\" action and going into sleep mode until new signal captured"
elif [ $RUNNING ]; then
echo "Going into sleep mode until new signal captured"
fi
if [ $ACTION ] || [ $RUNNING ]; then
while true; do
[ "$ACTION" == 'start' ] && start
[ "$ACTION" == 'stop' ] && stop
[ "$ACTION" == 'restart' ] && restart
[ "$ACTION" == 'alarm' ] && alarm
sleep 2
done
fi
'service myservice restart'를 바로 종료하는 대신'service myservice restart &'를 실행할 수 없습니까? –
당신이 링크 한 것은'init.d' 스타일의 서비스 스크립트입니다. 똥감을 사용하고 있습니까? – coderanger
저는이 요리사의 요리 책 (https://github.com/hw-cookbooks/runit)을 사용하고 있습니다. 나는 그것이 똥 벌레라고 확신한다. – Doron