如何将我的循环 Bash 脚本作为服务运行?



我有 2 个运行 HAProxy 的 Amazon Linux EC2 实例。我想从另一个实例监控每个实例,如果一个实例不可用,另一个实例将发出 API 命令将弹性 IP 移动到活动服务器。

我创建了一个 Bash 脚本来每 XX 秒进行一次监控。我需要将脚本设置为作为服务运行,因此我创建了一个服务包装器,并根据我找到并注册为服务的模板放置在/etc/init.d 中。

问题是当我 #service hamonitor 启动发出命令时,它说"正在启动 hamonitor...",但我从未看到 OK 消息,如果我发出停止命令,它会失败,如果我发出状态命令,它说它没有运行。但是,如果我检查日志,它会显示脚本实际上正在运行。我假设我需要一个适当的 PID 文件和/或由于脚本在无限循环中运行,它永远不会完成,因此不会发出 OK。

服务包装器:

#!/bin/sh
#
# /etc/init.d/hamonitor
# Subsystem file for "hamonitor" server
#
# chkconfig: 2345 95 05 (1)
# description: hamonitor server daemon
#
# processname: hamonitor
### BEGIN INIT INFO
# Provides: 
# Required-Start: 
# Required-Stop: 
# Should-Start: 
# Should-Stop: 
# Default-Start: 
# Default-Stop: 
# Short-Description: 
# Description:      
### END INIT INFO
# source function library
. /etc/rc.d/init.d/functions
PROG=hamonitor
EXEC=/etc/haproxy/hamonitor
LOCKFILE=/var/lock/subsys/$prog
PIDFILE=/var/run/$prog.pid
RETVAL=0
start() {
echo -n $"Starting $PROG:"
echo
#daemon $EXEC &
/etc/haproxy/hamonitor &
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
touch LOCKFILE
touch PIDFILE
echo "[ OK ]"
else
echo "[ FAIL: ${retval} ]"
fi
return $RETVAL
}
stop() {
echo -n $"Stopping $PROG:"
echo 
killproc $PROG -TERM
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
rm -f LOCKFILE
rm -f PIDFILE
echo "[ OK ]"
else
echo "[ FAIL: ${RETVAL} ]"
fi
return $RETVAL
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status $PROG
RETVAL=$?
;;
restart)
stop
start
;;
*)
echo $"Usage: $0 {start|stop|status|restart}"
RETVAL=1
esac
exit $RETVAL

应用程序:

#!/usr/bin/env bash
export EC2_HOME=/opt/aws/apitools/ec2
export JAVA_HOME=/usr/lib/jvm/jre
AWS_ACCESS_KEY="XXXXXXXXXXXXXXXXXXXXXXXXX"
AWS_SECRET_KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
VIP1="1.2.3.4"
VIP1_ALLOCATIONID="eipalloc-XXXXXXX"
THIS_NODE_EC2_ID="i-XXXXXXX"
THIS_NODE_PRIVATE_IPADDRESS1="10.60.0.11" 
THIS_NODE_HEALTHCHECK_URL="http://10.60.0.10/haproxy?monitor"
OTHER_NODE_HEALTHCHECK_URL="http://10.60.49.50/haproxy?monitor"
CHECK_OTHER_INTERVAL=5
CHECK_OTHER_FAIL_COUNT=0
CHECK_OTHER_RUN_COUNT=0
AFTER_TAKEOVER_WAIT=30
function takeover_vips {
/opt/aws/bin/ec2-associate-address -aws-access-key ${AWS_ACCESS_KEY} -aws-secret-key ${AWS_SECRET_KEY} -a ${VIP1_ALLOCATIONID} -i ${THIS_NODE_EC2_ID} -private-ip-address ${THIS_NODE_PRIVATE_IPADDRESS1} -allow-reassociation > /dev/null
}
function does_this_node_have_ips {
is_active=$(/opt/aws/bin/ec2-describe-addresses -aws-access-key ${AWS_ACCESS_KEY} -aws-secret-key ${AWS_SECRET_KEY}  | grep ${VIP1} | grep ${THIS_NODE_EC2_ID})
if [ "$is_active" = "" ]; then
echo "no"
else
echo "yes"
fi
}
function log_msg {
msg=$1
msg="$(date) -- ${msg}"
echo ${msg} >> /var/log/hamonitorlog
}
while [ . ]; do
healthcheck_response=$(curl -sL -w "%{http_code}" ${OTHER_NODE_HEALTHCHECK_URL} -o /dev/null) 
if [ "$healthcheck_response" != "200" ]; then
CHECK_OTHER_FAIL_COUNT=$((CHECK_OTHER_FAIL_COUNT+1))
if [ "$CHECK_OTHER_FAIL_COUNT" -gt 2 ]; then
takeover_vips
CHECK_OTHER_FAIL_COUNT=0
sleep ${AFTER_TAKEOVER_WAIT}
fi
sleep ${CHECK_OTHER_INTERVAL}
done

一些 Linux 发行版有upstart和其他init;我假设你有init. 该chkconfig用于维护符号链接。 您应该确认评论,

# chkconfig: 2345 95 05 (1)

适用于您的系统。

作为猜测,您需要通过脚本调用daemon。 这可能是某些init脚本库中的脚本函数,如/etc/rc.d/init.d/functions。 我建议您使用daemon()函数(如果存在)。 也

daemon $EXEC &                                               #option1
nohup /etc/haproxy/hamonitor < /dev/null > /dev/null 2>&1 &  #option2
/etc/haproxy/hamonitor&                                      #option3, 2 lines.
disown $!                                                    #...

这与 SIGCHLD 和进程返回状态有关(有关详细信息,请参阅man wait)。 同样,您可能需要将hamonitor与控制终端分离。 在这种情况下,您可以使用logger将信息发送到系统日志;我想应用程序脚本是hamonitor代码? 只需将echo更改为logger即可。

如果hamonitor需要stdoutstdin和/或stderr,您可能需要重定向到其他文件(如果需要)。 如果是这种情况,您也可以考虑通过screen运行它。

编辑:最后一个选项可用于创建适当的PIDFILE。 例如

# !!! optional grabbing of lock here...
/etc/haproxy/hamonitor &   # spawn in bg
HA_PID=$!                  # record spawn pid
echo $HA_PID > $PIDFILE    # record the PID to a file for `stop`.
# !!! optional release of lock here...
disown $HA_PID             # detach script from terminal.

服务不应使用echo等;logger是更好的选择。 这可能不是你的问题,除非hamonitor试图从某些东西中读取。 主要是问题是,如果你不disownstart()会等待hamonitor完成,所以rc脚本的开始永远不会完成。

一般来说,您可以查看/etc/rc.d/init.d/functions,提供指向您的文件的链接,或提供您的发行版和版本(或者至少是Linux 标准基本一致性,这似乎定义了它应该如何在其不同版本中工作)。 该文件在每个 Linux 上都可以不同。 如果您了解脚本编写,则可以自己查看此文件,以了解需要哪些环境变量、文件等以及在此文件中使用哪些函数。 例如,killproc很可能在那里定义。

相关内容

  • 没有找到相关文章