Непрерывный пинг-цикл в скрипте

Хорошо, я понимаю, что здесь происходит. Я видел ту же проблему при попытке настроить 3-узловой кластер Spring-XD в Vagrant на виртуальных машинах Linux.

Эта конфигурация работала:

server.1=172.28.128.3:2888:3888
server.2=172.28.128.4:2888:3888
server.3=172.28.128.7:2888:3888

Но эта не работала:

server.1=spring-xd-1:2888:3888
server.2=spring-xd-2:2888:3888
server.3=spring-xd-3:2888:3888

«Дымящимся пистолетом» была эта строка в моем журнале zookeeper:

2015-11-26 20: 48: 31,439 [myid: 1 ] - ИНФОРМАЦИЯ [Thread-2: QuorumCnxManager $ Listener @ 504] - Мой порт привязки выборов: spring-xd-1 / 127.0.0.1: 3888

Итак, почему была привязка Zookeeper порт выбора на интерфейсе обратной связи? Хорошо...

Мои / etc / hosts на одной из виртуальных машин выглядели так:

127.0.0.1   spring-xd-1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

## vagrant-hostmanager-start
172.28.128.3    spring-xd-1
172.28.128.4    spring-xd-2
172.28.128.7    spring-xd-3
## vagrant-hostmanager-end

Я удалил имя хоста из строки 127.0.0.1 в / etc / hosts и отказал службе zookeeper на всех 3 узлах, и БАМ! Все вышло розами. Итак, теперь файл хоста на каждой машине выглядит так:

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

## vagrant-hostmanager-start
172.28.128.3    spring-xd-1
172.28.128.4    spring-xd-2
172.28.128.7    spring-xd-3
## vagrant-hostmanager-end

Я предполагаю, что вы не видели проблемы в Windows, потому что файл хостов ( C: \ Windows \ System32 \ drivers \ etc \ hosts ) по умолчанию не имеет записей. Вы сможете воспроизвести проблему в Windows, добавив к ней аналогичную строку 127.0.0.1 .

Я называю это ошибкой Zookeeper. Редактировать файл hosts было достаточно, чтобы доказать проблему и исправить ее в Vagrant, но я бы не рекомендовал его для любой «реальной» среды.

РЕДАКТИРОВАТЬ: Согласно http://ccl.cse.nd.edu/operations/condor/hostname.shtml , это, по-видимому, довольно распространенная проблема с кластерными приложениями в Linux, и рекомендует редактировать файл hosts, как я описал выше. Однако в документации Zookeeper по настройке кластера это не упоминается.

3
19.07.2018, 16:51
3 ответа

Вы имеете в виду что-то настолько простое, как это?:

while :; do
   ping -c 1 -w 3 8.8.8.8; echo $? > /tmp/ping.status
   sleep 1
done

Это будет записывать статус выхода pingв /tmp/ping.statusодин раз в секунду. Затем в другом скрипте у вас может быть что-то вроде:

pingFailed=$(cat /tmp/ping.status)
if [ $pingFailed -ne 0 ]; then
    echo "No connection"
else
    echo "Connected!"
fi

Так что да, вы могли бы сделать это. Тем не менее, это действительно плохой метод проверки вашего соединения. Очевидно, здесь есть условия для гонки. То, что соединение было активным во время выполнения первого цикла, не означает, что оно активно и сейчас. Что еще более важно, если вы читаете файл ping.statusв начале скрипта, это не означает, что соединение останется в его конце. Кроме того, вы засоряете сеть и процессор непрерывными запросами. Это действительно не очень элегантно.

Более быстрый и простой способ проверки работоспособности соединения (по крайней мере в Linux )— это просмотр /sys/class/net/$NIC/link_mode, где $NIC— имя вашей сетевой карты. Например, в моей системе:

## Wireless connection up
$ cat /sys/class/net/wlp3s0/link_mode 
1
## Wireless connection down
$ cat /sys/class/net/wlp3s0/link_mode 
0

Вы можете написать функцию, которая проверяет это:

isLinkDown(){
    return $(cat /sys/class/net/wlp3s0/link_mode)
}

И вы можете использовать его в своих скриптах вот так:

if isLinkDown; then 
    echo Link Down
else
    echo Link Up
12
27.01.2020, 21:08

ответ тердона хорош, но я бы избегал раздувания сети,

но сначала в сторону ; pingможет занять всего 0,002 с до 8.8.8.8, поэтому, если вы хотите протестировать сеть с низкой задержкой,

$ timeout 0.1 ping -c 1 8.8.8.8

можно использовать, чтобы гарантировать 1/10 секунды времени тестирования (, поскольку время ожидания ping не составляет доли секунды ).

Теперь ответ на оптимизацию скорости и использования сети; вы должны сделать так, чтобы ваши скрипты передавали параметры;

#!/bin/bash

usage() {
    echo "Usage: $0 [OPTIONS]"
    echo " OPTIONS:"
    echo "  -h     this Help message"
    echo "  -n     do Not re-test network connectivity"
}

NO_TEST=false
while getopts "nh" OPT; do
    case "$OPT" in
        n)
            NO_TEST=true
            ;;
        h)
            usage
            exit 0
            ;;
        *)
            echo "unsupported option $OPT" >&2
            usage
            exit 1
            ;;
    esac
done
shift $((OPTIND - 1))

if ! $NO_TEST && ! ping -c 1 -w 3 8.8.8.8; then
    echo "no connection" >&2
    exit 2
fi
echo "do stuff";
3
27.01.2020, 21:08

Спасибо всем за ответы! Мне просто нужно немного времени, чтобы принять во внимание некоторые из ваших ценных мыслей. Чтобы прояснить некоторые вещи, я просто хочу добавить, что:
1. Я не могу использовать параметры, так как большинство этих скриптов работают либо в init.d, либо запускаются cron.
2. Вся идея в основном создается для модемного подключения. А задержки пинга зависят от силы сигнала. Я даже не уверен, могу ли я уменьшить интервал проверки пинга ниже 1 с, чтобы иметь надежные проверки при низком уровне сигнала, но соединение все еще существует. Вот почему я подумал, что цикл пинга с интервалом по умолчанию, который просто выводит результат в какое-то легкодоступное место, будет лучшим компромиссом.

Это то, что я использовал совсем недавно

modemup(){
    echo -e "AT+QRST=1,0\r\n" > /dev/ttyUSB2
    ifdown $INTERFACE && ifup $INTERFACE

    if [ "$(ifconfig | grep $INTFC_NAME)" ]; then
        return 0
    else
        echo "Cant start modem interface"
        return 1
    fi
  } 

reconnect(){
    MAX_ATTEMPTS=$1 #number of tries before reboot
    TRIES=1

    while [ $TRIES -le $MAX_ATTEMPTS ]; do
        echo "Trying to reconnect..."
        echo "Number of try: $TRIES"
        modemup
        /etc/init.d/network restart
        sleep 10
        if [ "$(ping -c 1 -w 3 8.8.8.8)" ]; then
            break
        fi
        : $((TRIES+=1))
    done
    echo "Tried $MAX_ATTEMPTS times, couldnt reconnect. Rebooting..."
    reboot
}

while true; do
    if [ "$(ping -c 1 -w 3 8.8.8.8)" ]; then
         rm -rf $NOCONFILE #if noconnection file exists delete it
    else
        mkdir -p $LOG_DIR/${DAY_DIR}
        TIME=`date +%Y%m%d%H%M%S`
        echo "$TIME: Connection lost" 2>&1 | tee -a $LOG_FILE
        touch $NOCONFILE
        reconnect $ATTEMPTS 2>&1 | tee -a $LOG_FILE   
    fi
    sleep $INTERVAL
done
0
27.01.2020, 21:08

Теги

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