Вопрос

У меня есть несколько серверов и других демонов, которые мне нужно запустить в правильной последовательности.

Я создал сценарии init.d из скрипта skeleton и могу установить их для запуска в правильной последовательности, используя систему нумерации имен, но остается несколько проблем:

Одному серверу ('ServerA') необходимо инициализировать подключение к базе данных, а затем прослушать сокет.Затем другой сервер ('ServerB') должен подключиться к этому сокету, и соединение завершится ошибкой, если предыдущий процесс еще не прослушивается.Есть ли способ предотвратить завершение сценария init.d для ServerA до тех пор, пока ServerA не начнет прослушивание?Инициализация ServerB не запустится до тех пор, пока инициализация ServerA не завершится.

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

Это было полезно?

Решение

Да, это мой вопрос, на который я отвечаю, но я нашел эту технику полезной и делюсь ею со всеми, кто еще борется с подобными проблемами.

Я обнаружил, что socat очень полезен при ожидании сокета или порта.Скрипт init.d, подобный:

case “$1″ in
  start)
  echo '--benign phrase' | socat - UNIX-CONNECT:/path/to/socket,retry=10,intervall=1
;;

будет ждать, пока сокет не станет доступным для записи, затем вернется.Здесь не задействована демонизация, поэтому она блокирует выполнение скриптов init.d с более высоким номером до их завершения.

Использование таких сценариев waiter замедлит последовательность загрузки и, следовательно, неоптимально, но является большим улучшением по сравнению с очень хрупким подходом, заключающимся в разбрызгивании инструкций 'sleep n' в сценариях.

Другие советы

Я не думаю, что это хрупко - по крайней мере, я могу придумать сценарий, в котором это не будет хрупким.Имейте время повторения в 5 секунд, и это совсем неплохо.это подход к поцелую, и нет никаких угловых случаев, которые вы не понимаете.

Синхронизация распределенной среды не для слабонервных, и в вашем примере это излишество.

Чтобы придать вам некоторую уверенность в вашем подходе, я могу сказать вам, что у меня есть десятки написанных вручную сложных серверных процессов, распределенных по веб-ферме, они никогда не доставляли мне никаких огорчений, даже когда исчезали серверы баз данных, или когда выходили из строя сетевые магистрали и т.д.Они просто продолжают работать в ухудшенном режиме до тех пор, пока базы данных не вернутся.

Если сервер прослушивает доменный сокет, вы могли бы создать цикл, который опрашивает сокет.Возможно, есть более простой способ сделать это в bash, но это может выглядеть примерно так:

for i in 1 2 3 4 5; do
  if [ -e '/var/run/myserver.sock' ]; then
    break
  fi
done

Другое решение заключается в том, чтобы ваш сервер не демонизировался до тех пор, пока он не откроет прослушивающий сокет.Таким образом, сценарий инициализации будет приостановлен до тех пор, пока процесс не демонизируется, что гарантирует доступность сокета.

Конечно, это зависит от того, выполняет ли ваше приложение демонизацию само по себе, а не с помощью каких-либо других средств.("/usr/bin/myserver &" или тому подобное.)

Обновленный:

Также обратите внимание, что все, что вы делаете сейчас, - это инициализация в стиле System-V.Ubuntu на самом деле использует Upstart, который представляет собой систему, основанную на событиях, а не последовательность сценариев.Вы могли бы выбрать использование заданий upstart, а не сценариев инициализации System-V, и запустить пользовательское событие Upstart с вашего сервера, которое вызовет запуск вашего второго сервера.

В Руководство по началу работы пример этого приведен в самом низу.Я не знаю, есть ли способ API, но это может быть просто вопросом “system("/bin/initctl emit myevent");” в нужный момент времени на вашем первом сервере.Кто-то другой, обладающий большим опытом работы с новичками, возможно, сможет разработать проект лучше / глубже.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top