以 ssh 会话终止的初始化脚本

以 ssh 会话终止的初始化脚本

我们需要跑pt-stalk在少数服务器上监视 mySQL,每次服务器重启时我都手动启动它,这让我厌烦不已。谷歌搜索后,我找到了一个初始化脚本对于 pt-stalk,它似乎工作得很好。[我稍作修改的版本包含在这篇文章的底部]

花了太长时间才弄清楚如何通过 ssh 推送脚本和配置 [说来话长,请不要问] 所以我决定登录到 20 多个服务器并手动设置一切,一切都正常了。

几天后,我的同事说他收到了电子邮件,但我显然没有收到,看来我在配置中输入了错误的电子邮件。这次我弄清楚了如何通过 ssh 推送更改,并完成了所有操作:

for server in `cat serverlist.txt`; do
  ssh -t $server sudo -i service pt-stalk restart
done

这是 pt-stalk 在每个服务器上停止工作的地方:

2013_08_23_11_43_20 Caught signal, exiting
2013_08_23_11_43_20 Exiting because OKTORUN is false
2013_08_23_11_43_20 /usr/bin/pt-stalk exit status 1
2013_08_23_11_43_22 Starting /usr/bin/pt-stalk --function=status --variable=Threads_connected --threshold=100 --match= --cycles=5 --interval=1 --iterations= --run-time=30 --sleep=300 --dest=/var/lib/pt-stalk --prefix= [email protected] --log=/var/log/pt-stalk.log --pid=/var/run/pt-stalk.pid
2013_08_23_11_43_22 Caught signal, exiting

通过昨天的测试,我明白了“捕获信号,退出”意味着它捕获了HUP/ TERM/ KILL。第一个来自service pt-stalk restart,而第二紧接着成功的开始时间是从 ssh 会话关闭时开始的。wat.jpg

如果我只是 ssh 到服务器,输入sudo -i service pt-stalk startrestart注销,它就会顺利继续。但是,如果我只是像上面的 loop pt-stalk 一样向 ssh 输入命令,它会捕获信号并退出。有时它会捕获退出之前发出信号。

这到底是怎么回事?


我的 /etc/init.d/pt-stalk 供参考:

#!/usr/bin/env bash
# chkconfig: 2345 20 80
# description: pt-stalk
### BEGIN INIT INFO
# Provides: pt-stalk
# Required-Start: $network $named $remote_fs $syslog
# Required-Stop: $network $named $remote_fs $syslog
# Should-Start: pt-stalk
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
### END INIT INFO

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON="/usr/bin/pt-stalk"
DAEMON_OPTS="--config /etc/pt-stalk.conf"
NAME="pt-stalk"
DESC="pt-stalk"
PIDFILE="/var/run/${NAME}.pid"
STALKHOME="/var/lib/pt-stalk"

test -x $DAEMON || exit 1

[ -r /etc/default/pt-stalk ] && . /etc/default/pt-stalk

#. /lib/lsb/init-functions

sig () {
    test -s "$PIDFILE" && kill -$1 `cat $PIDFILE`
}

start() {
  if [[ -z $MYSQL_OPTS ]]; then
HOME=$STALKHOME $DAEMON $DAEMON_OPTS
  else
HOME=$STALKHOME $DAEMON $DAEMON_OPTS -- $MYSQL_OPTS
  fi
return $?
}

stop() {
  if sig TERM; then
    while sig 0 ; do
      echo -n "."
      sleep 1
    done
    return 0
  else
    echo "$DESC is not running."
    return 1
  fi
}

status() {
  if sig 0 ; then
    echo "$DESC (`cat $PIDFILE`) is running."
    return 0
  else
    echo "$DESC is stopped."
    return 1
  fi
}

log_begin_msg() {
        echo $1
}

log_end_msg() {
        if [ $1 -eq 0 ]; then
                echo "Success"
        else
                echo "Failure"
        fi
}

case "$1" in
  start)
   log_begin_msg "Starting $DESC"
   start
   log_end_msg $?
   ;;

  stop)
   log_begin_msg "Stopping $DESC"
   stop
   log_end_msg $?
   ;;
  status)
    status ;;

  restart)
    log_begin_msg "Restarting $DESC"
    stop
    sleep 1
    start
    log_end_msg $?
    ;;

  *)
    echo "Usage: $0 {start|stop|status|}" >&2
    exit 1
    ;;
esac

答案1

由于您的守护进程立即终止,我很确定如果--daemonize给出该选项,/usr/bin/pt-stalk它可能不会关闭其中一个文件描述符stdinstdout或者stderr不能正确且足够早地关闭或/并且不能SIGHUP正确处理信号。

为了测试我的哪个假设是正确的,请修改init脚本,以便的输入和输出start从和重定向到/dev/null。例如:

start </dev/null >/dev/null 2>/dev/null

如果这消除了提前终止问题,则通过再次逐个删除这些重定向来缩小范围。可能只是pt-stalk分叉太早了。在这种情况下,sleep 1在调用后插入另一个start可能也能解决这个问题。如果它涉及到信号的处理,那么通过添加以下内容SIGHUP来修改脚本也可能是一种解决方法:init

trap "echo SIGHUP ignored" 1

在调用之前,start如下所示:

trap - 1

调用后立即start

我没有下载pt-stalk,也没有查看它,也没有测试我上面描述的理论。这些都是我使用其他守护进程的经验。

相关内容