monit: как я перезапускаю многих Котов, не перегружая сервер?

Мой сервер имеет несколько отдельных экземпляров Tomcat Apache, которые каждый занимает много времени и ЦП для запуска. Не возможно запустить всех их одновременно. Это генерировало бы слишком много ввода-вывода, каждый сервис возьмет намного дольше для запуска, и сервисы даже могли бы не запуститься из-за внутренних тайм-аутов.

Вот некоторый псевдо код, который описывает то, что я хочу сделать. Как я выполнил бы это с monitrc файлом?

check process service01 with pidfile /var/run/service01.pid
    start program = "/usr/sbin/service service01 start" with timeout 60 seconds
    stop program  = "/usr/sbin/service service01 stop"
    if does not exist then
        wait a random number of seconds (between 2 and 5 minutes)
        if the cpu load is < 100% then
            start program
        else 
            do nothing (check again in the next cycle)

check process service02 with pidfile /var/run/service02.pid
....

Этот блок кода был бы повторен для каждого из этих 10 сервисов.

Критический шаг является случайным ожиданием. Иначе, если сервер неактивен, и никакая услуга не работает (например, после 'killall-9 Java'), monit проверил бы все сервисы, находит, что загрузка ЦП является низкой прямо сейчас, и запустите все сервисы сразу.

0
задан 2 August 2015 в 10:17
2 ответа

Я теперь выяснил настройку, которая делает работу. После перезагрузки или после сбоя нескольких процессов проверяется загрузка процессора, и каждая служба запускается только после того, как загрузка процессора опускается ниже 1 или после длительной задержки. Скрипты ниже отлично работают в моей среде:

Редактирование /etc/monit/monitrc:

...
## Start Monit in the background (run as a daemon):
#
set daemon 120              # check services at 2-minute intervals
    with start delay 240    # optional: delay the first check by 4-minutes (by
#                           # default Monit check immediately after Monit start)

Для каждой службы добавьте это в /etc/monit/conf.d:

check process myname with pidfile /var/run/app0000.pid
    start program = "/usr/sbin/service app0000 start" with timeout 60 seconds
    stop program  = "/usr/sbin/service app0000 stop"
    if does not exist then exec "/root/bin/service_with_delay app0000 start"

Создание скрипта /root/bin/service_with_delay:

#!/bin/bash
(
  # Wait for lock on /var/lock/service_with_delay.lock (fd 9)
  flock -n 9 || exit 1

  for i in `seq 1 10`; do

    # start the service if the cpu load is < 1.0 or after waiting for 300 seconds

    read load ignore </proc/loadavg
    flag=`expr ${load} '<' 1`
    if [ ${flag} -eq 1 ] || [ ${i} -eq 10 ]; then

        echo `date` service_with_delay $1: pid $$ load ${load} i ${i} - starting >> /var/log/service_with_delay.log
        /usr/sbin/service $1 start

        # make sure next script getting the lock sees some load
        sleep 60
        break
    fi

    # wait
    echo `date` service_with_delay $1: pid $$ load ${load} i ${i} >> /var/log/service_with_delay.log
    sleep 30
  done
) 9> /var/lock/service_with_delay.lock
0
ответ дан 5 December 2019 в 12:30

Вы мало что рассказали о своей ОС, я могу только предположить, что это Linux (из части kill -9 ... ). Я также мало знаю о monit , но предполагаю, что это гибкое решение, позволяющее повторно запустить службу в случае сбоя.

Я предполагаю, что экземпляры Tomcat запускаются с помощью сценария запуска оболочки (s ). Добавьте где-нибудь в начале этих скриптов:

# edit the 3 lines to set your limits
LOAD_THRESHOLD=0.75
LOCK_TIME=30
TIME_LIMIT=120

LOCK_FILE='/var/lock/tomcat-delay.lock'

if [ -z "${TOMCAT_NOLOCK}" ]; then
    # simple locking mechanism to avoid simultaneous start of instances
    if [ -f "${LOCK_FILE}" ] && [ $(cat "${LOCK_FILE}") -gt $(date '+%s') ]; then
        exit 1
    else
        expr $(date '+%s') + ${LOCK_TIME} 1>"${LOCK_FILE}"
    fi
fi

T_TIME=0
while true; do
    # check for non-empty TOMCAT_NOWAIT
    if [ -n "${TOMCAT_NOWAIT}" ]; then
        break 1
    fi
    read T_LOAD60 T_REST </proc/loadavg
    # check current 60 sec. average value for system load
    if expr ${T_LOAD60} '<' ${LOAD_THRESHOLD} 1>/dev/null; then
        break 1
    fi
    # check for timeout
    if [ ${T_TIME} -ge ${TIME_LIMIT} ]; then
        # change to 'exit 1' to fail on timeout instead of proceeding
        break 1
    fi
    sleep 1s
    echo -n '.'
    T_TIME=$((${T_TIME} + 1))
done

Приведенный выше код на самом деле проверяет не только загрузку процессора, а скорее среднюю загрузку системы, которая по замыслу включает все факторы, которые могут замедлить вашу производительность. TIME_LIMIT в секундах. Сценарий, наконец, попытается запустить вашу службу, если нагрузка не упадет ниже заданного порога за заданное время - последняя часть break 1 может быть изменена на exit 1 , чтобы прервать запуск и сообщить демон monit , чтобы повторить попытку.

Если вы попытаетесь запустить службу вручную (не из monit ), он также будет ждать, что я считаю преимуществом. Чтобы избежать этого, вы можете экспортировать env TOMCAT_NOWAIT с непустым значением.

Редактировать №1: добавил простой механизм блокировки в качестве обходного пути для решения проблемы одновременного запуска экземпляров. Непустой env TOMCAT_NOLOCK отключает блокировку. Установите LOCK_TIME на время разогрева экземпляров, чтобы высокая нагрузка определялась правильно.

0
ответ дан 5 December 2019 в 12:30

Теги

Похожие вопросы