Как упорядочить скрипты init.d под Ubuntu - PullRequest
0 голосов
/ 05 декабря 2009

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

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

Один сервер ('serverA') должен инициализировать соединение с базой данных, а затем прослушивать сокет. Другой сервер ('serverB') затем должен подключиться к этому сокету, и соединение не будет установлено, если предыдущий процесс еще не прослушивает. Есть ли способ предотвратить завершение сценария init.d для сервера A, пока сервер A не начнет слушать? InitB сервера не запустится, пока initA server не завершится.

В данный момент установка работает так, что serverB просто повторяет соединение, пока оно не установится, но такой подход кажется хрупким. Я хотел бы получить более детерминистическое понимание того, как форсировать последовательность.

Ответы [ 3 ]

3 голосов
/ 22 февраля 2010

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

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

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

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

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

2 голосов
/ 05 декабря 2009

Если сервер прослушивает сокет домена, вы можете создать цикл, который опрашивает сокет. В 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 с вашего сервера, что приведет к запуску вашего второго сервера.

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

2 голосов
/ 05 декабря 2009

Я не думаю, что это хрупко - по крайней мере, я могу думать о сценарии, где он не будет хрупким. Повторите попытку 5 секунд, и это совсем не плохо. Это подход ПОЦЕЛУЯ, и нет никаких крайних случаев, которые вы не понимаете.

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

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

...