Agenten automatisch neustarten

Ausgangssituation

Einzelne Agenten weisen wiederholt einen undefinierten Stand auf, Jobs und Filetrransfers auf diesen Agenten brechen ab. Laut der Systemübersicht und dem Service Manager sind sie nicht mehr aktiv bzw. sogar abgebrochen, aber auf der Maschine selber laufen die benötigten Prozesse noch. Ein automatischer Neustart der Prozesse wurde daher auf dem Server nicht angestoßen.

 Lösungsansatz

Das Problem läßt sich mit einem Job, der mit UC4 Mittel den Status eines Agenten prüft, lösen. Die Prüfungen finden dabei auf zwei Ebenen statt:

  • mit UC4 Scriptmitteln (SYS_HOST_ALIVE) wird geprüft, ob ein bestimmter Host (Agent) aktiv ist.
  • mit einem UC4 Tool resp. Dienstprogramm (ucybsmcl: UC4 Process Viewer) wird der Status des Agenten geprüft.

Signalisieren beide Abfragen einen aktiven Agenten, so liegt mit hoher Warscheinlichkeit kein Problem vor. Liefern die beiden Abfragen unterschiedliche Ergebnisse, so liegt definitv ein Problem vor. Melden beide Abfragen, daß der Agent nicht aktiv ist, so kann das durchaus in Ordnung sein - der Agent kann ja gezielt beendet worden sein.

Da der Einsatz der UC4 Scriptmittel zur Generierungszeit des Jobs ausgeführt werden, der Aufruf des Dienstprogrammes jedoch zur Laufzeit des Jobs, kann es sinnvoll sein, den Job erst zur Laufzeit generieren zu lassen. Dies ist der Fall, wenn der Prüfjob bspw. in einer Batchkette laufen soll.

Beispiel

Ein kleines Programmbeispiel soll die Lösung verdeutlichen. (Die einzelnen erforderlichen UC4 und shell Variablen werden nicht explizit initialisiert.)

# ###################
# globals
# ###################

set -u        # abort if vars are not set

uc4_RC=0
echo "executor to check: &executor2check#"
echo "portnumber:        $PORTNUMMER"
echo "current host:      `hostname`"

uc4_script_says_executor_is_alive=0
ucybsmcl_says_executor_is_alive=0
delimiter="------------------------------------------------"
pass_arg=""

# ###################
# set_rc
# ###################

set_rc() {
if test $# -gt 0 ; then
rc=$1
echo "RC of last cmd: $rc"
if test $rc -ne 0 ; then
uc4_RC=`expr $uc4_RC + 1`
fi
else
echo "internal error: got $# no. of args, expecting 1: ABORT!"
exit 1
fi
}

# ###################
# get_pwd
# ###################

get_pwd() {
if test -r &wrk_file# ; then
ls -la &wrk_file#
smgr_pwd=`cat &wrk_file#`
pass_arg="-p '$smgr_pwd'"
!! TEST TEST TEST
!    echo "smgr pwd == $smgr_pwd"
!! TEST TEST TEST
rm -rf &wrk_file#
if test -r &wrk_file# ; then
echo "cannot REMOVE &wrk_file# do it manually: ABORT!"
exit 1
fi
else
echo "cannot access &wrk_file#: ABORT!"
exit 1
fi
}

# ###################
# main
# ###################

! 00: read smgr password
! ----------------------

:if &smgr_pwd# <> ""
get_pwd
:else
echo "no password for smgr set: skipping -p arg!"
:endif

! 01: check via UC4 script whether executor ist running
! -----------------------------------------------------
:set &primary_alive# = SYS_HOST_ALIVE(&executor2check#)
:if &primary_alive# = "Y"
:  p "UC4 script says: executor &executor2check# is running."
/usr/bin/echo "$delimiter\n01: UC4 script says: executor &executor2check# is running."
uc4_script_says_executor_is_alive=1
:else
:  p "UC4 script says: executor &executor2check# is NOT running: poss restart required."
/usr/bin/echo "$delimiter\n01: UC4 script says: executor &executor2check# is NOT running: poss. restart required"
uc4_script_says_executor_is_alive=0
:endif

if test -d &UC4_SMGR# ; then
cd &UC4_SMGR#

! 02: ping to executor
! --------------------
/usr/bin/echo "$delimiter\n02: ping -c 3 -w 5 &executor2check# .."
ping -c 3 -w 5 &executor2check#
RC=$?
if test $RC -ne 0 ; then
echo "02: cannot reach &executor2check# via DNS, rc = $RC: ABORT!"
exit $RC
fi

! 03: check via service manager whether executor ist active
! ---------------------------------------------------------
/usr/bin/echo "$delimiter\n03a: checking state for &executor2check# via &host#"
ksh "./ucybsmcl -c GET_PROCESS_LIST -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE#"
RC=$?
set_rc $RC
if test $RC -eq 0 ; then
# je nach UC4 System/Anzahl Executoren die erforderlichen egrep Filter setzen!
# 1. Fall: Executor ist nur an einem System angebunden:
#          PR: immer "&executor2check_uc#"
#          ST: immer "&executor2check_uc#"
# 2. Fall: Executor ist in mehreren Systemen angebunden:
#          PR: immer "&executor2check_uc#"
#          ST: immer "&executor2check_uc#_&uc4_system#"

tmp=`ksh "./ucybsmcl -c GET_PROCESS_LIST -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE#" | wc -l | tr -d ' '`
echo "entries in ucybsmcl PROCESS_LIST: $tmp"
if test $tmp -eq 1 ; then
FILTER='&executor2check_uc#"'
else
:if &uc4_system# = "UC4ST"
FILTER='&executor2check_uc#_&uc4_system#"'
:else
FILTER='&executor2check_uc#"'
:endif
fi
echo "using egrep filter $FILTER"
PROCESS_NAME=`ksh "./ucybsmcl -c GET_PROCESS_LIST -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE#" | egrep "$FILTER" | cut -f 2 -d "\""`
echo "PROCESS_NAME: $PROCESS_NAME"
PROCESS_STATE=`ksh "./ucybsmcl -c GET_PROCESS_LIST -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE#" | egrep "$FILTER" | cut -f 4 -d "\""`
echo "PROCESS_STATE: $PROCESS_STATE"
if test "x$PROCESS_STATE" = "xR" ; then
echo "03c: ucybsmcl says, executor &executor2check# has status $PROCESS_STATE, i.e. running"
ucybsmcl_says_executor_is_alive=1
else
echo "03c: ucybsmcl says, executor &executor2check# has status $PROCESS_STATE, i.e. NOT running: poss. restart required"
ucybsmcl_says_executor_is_alive=0
fi
else
echo "03b: ucybsmcl GET_PROCESS_LIST returned rc $RC: cannot process further"
exit $RC
fi

! 04: check if service manager and UC4 script infos differ
! --------------------------------------------------------
sum=` expr $uc4_script_says_executor_is_alive + $ucybsmcl_says_executor_is_alive `
if test $sum -ne 2 0 ; then
/usr/bin/echo "$delimiter\n04: uc4_script_says_executor_is_alive == $uc4_script_says_executor_is_alive and ucybsmcl_says_executor_is_alive = $ucybsmcl_says_executor_is_alive: restart!"
:if &restart# = 1
:  p "restart = &restart#: Checking if executors &executor2check# has to be restarted"

! 05: service manager and UC4 script infos differ: restart executor
! -----------------------------------------------------------------
if test "x$PROCESS_STATE" = "xR" ; then
/usr/bin/echo "$delimiter\n05a: executor still running: stopping executor &executor2check#:$PORTNUMMER"
:if &major_version# = 6
./ucybsmcl -c STOP_PROCESS -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE# -s "$PROCESS_NAME" -m A
:else
ksh "./ucybsmcl -c STOP_PROCESS -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE# -s \"$PROCESS_NAME\" -m A $pass_arg"
:endif
RC=$?
set_rc $RC

echo "05b: checking state for &executor2check# via &host#"
ksh "./ucybsmcl  -c GET_PROCESS_LIST -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE#"
RC=$?
set_rc $RC

echo "05c: starting executor on &executor2check#."
:if &major_version# = 6
./ucybsmcl -c START_PROCESS -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE# -s "$PROCESS_NAME"
:else
ksh "./ucybsmcl -c START_PROCESS -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE# -s \"$PROCESS_NAME\" $pass_arg"
:endif
RC=$?
set_rc $RC

echo "05d: checking state for &executor2check# via &host#"
ksh "./ucybsmcl  -c GET_PROCESS_LIST -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE#"
RC=$?
set_rc $RC
else
/usr/bin/echo "$delimiter\n05a: executor already stopped: (re)starting executor &executor2check#."
:if &major_version# = 6
./ucybsmcl -c START_PROCESS -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE# -s "$PROCESS_NAME"
:else
ksh "./ucybsmcl -c START_PROCESS -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE# -s \"$PROCESS_NAME\" $pass_arg"
:endif
RC=$?
set_rc $RC

echo "05b: checking state for &executor2check# via &host#"
ksh "./ucybsmcl  -c GET_PROCESS_LIST -h &executor2check#:$PORTNUMMER -n &SMGR_PHRASE#"
RC=$?
set_rc $RC
fi

:  if &receiver# <> ""
! 06: sending email
! -----------------
:    p "sending infomring email to &receiver#"
:    set &my_name# = sys_user_name()
/usr/bin/echo "$delimiter\n06: sending email to &receiver#"
echo "Hallo Kollegen,

der Executor &executor2check# ist laut Scriptmitteln nicht aktiv: \
\
Status laut UC4 Script:       &primary_alive# \
Status laut Service Manager:  $PROCESS_STATE \
\
Der Executor wurde daher neu gestartet, RC = $uc4_RC. Bitte den Fehler analysieren.
\
Viele Grüße
\
&my_name#
" | mutt -s "Restart des Executors &executor2check# auf &umgebung#" &RECEIVER#
:  endif
:else
:  p "restart = &restart#: no check whether executor &executor2check# has to be restarted"
:endif
else
/usr/bin/echo "$delimiter\n04: uc4_script_says_executor_is_alive == $uc4_script_says_executor_is_alive and ucybsmcl_says_executor_is_alive = $ucybsmcl_says_executor_is_alive - all 1: nothing to do!"
fi
else
echo "cannot access dir &UC4_SMGR#: ABORT!"
exit 1
fi

echo "uc4_RC: $uc4_RC"
if test $uc4_RC -ne 0 ; then
echo "exiting mit error RC $uc4_RC"
exit $uc4_RC
fi