Хорошо, я понимаю, что здесь происходит. Я видел ту же проблему при попытке настроить 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 по настройке кластера это не упоминается.
Вы имеете в виду что-то настолько простое, как это?:
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
ответ тердона хорош, но я бы избегал раздувания сети,
но сначала в сторону ; 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";
Спасибо всем за ответы! Мне просто нужно немного времени, чтобы принять во внимание некоторые из ваших ценных мыслей. Чтобы прояснить некоторые вещи, я просто хочу добавить, что:
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