gpt4 book ai didi

linux - runit 的服务重新启动如何立即返回?

转载 作者:太空宇宙 更新时间:2023-11-04 12:49:10 27 4
gpt4 key购买 nike

我有一个 runit 服务,我用它来运行一个使用 unicornrails 应用程序。

它的重启命令使用信号 (USR2) 来处理零停机重启。基本上,它会等到新进程准备就绪,然后旧进程才会消亡。

这会导致很长(40 秒)的重启时间,其中 service myservice restart 直到结束才返回。

虽然我可以给 runit 一个更长的超时时间(我已经这样做了),但我想让这个重启成为一种即发即弃的 Action ,这样它会立即返回(或者在 USR2 信号被触发之后,但没有等待它完成。

整个逻辑取自多篇关于零停机时间 rails 部署和 unicorn 重启的博文:

这是 runit 脚本(由 chef 生成):

#!/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

最佳答案

这是一种使用 Runit 的 super 奇怪的方式,将您的重新加载逻辑移动到 control/h 脚本并使用 sv hup (或者因为它似乎没有不仅仅是发送 USR2 sv 2)。不应涉及主运行脚本。

关于linux - runit 的服务重新启动如何立即返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37763909/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com