2016-06-11 5 views
0

나는 어플을 unicorn으로 실행하는 데 사용하는 runit 서비스를 보유하고 있습니다.runit 서비스가 즉시 다시 시작될 수 있습니까?

재시작 명령은 신호 (USR2)를 사용하여 가동 중지 시간 제로 재시작을 처리합니다. 기본적으로 이전 프로세스가 종료되기 전에 새 프로세스가 준비 될 때까지 대기합니다.

이렇게하면 service myservice restart이 끝날 때까지 돌아 오지 않는 매우 긴 (40 초) 재시작 시간이 발생합니다.

runit에 더 긴 타임 아웃 (나는 이미하고있다.)을 줄 수 있지만, 나는 이것을 재발동 시켜서 즉시 반환 할 것이다. (또는 USR2 신호가 발사 된 후에도 .가 완료 될 때까지 기다리지 않고

전체 논리는 unicorn 다시 시작과 제로 다운 타임에 대한 여러 블로그 게시물에서 rails 배포를 가져온 것입니다

이이 (요리사에 의해 생성)을 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 
+0

'service myservice restart'를 바로 종료하는 대신'service myservice restart &'를 실행할 수 없습니까? –

+0

당신이 링크 한 것은'init.d' 스타일의 서비스 스크립트입니다. 똥감을 사용하고 있습니까? – coderanger

+0

저는이 요리사의 요리 책 (https://github.com/hw-cookbooks/runit)을 사용하고 있습니다. 나는 그것이 똥 벌레라고 확신한다. – Doron

답변

0

control/h 스크립트에 다시로드 논리를 이동하고 sv hup를 사용 (또는 왜냐하면 그것은 USR2 sv 2을 보내는 것 이상으로 보이지 않기 때문입니다. 기본 실행 스크립트가 포함되어서는 안됩니다.

+0

또한 reload_signal을 USR2로 설정하면 대부분을 자동화하는 poise-service 용 필수 플러그입니다. – coderanger