Как передать сокет прослушивания TCP с минимальным временем простоя? - PullRequest
8 голосов
/ 05 февраля 2010

Хотя этот вопрос помечен EventMachine, универсальные решения BSD-сокетов на любом языке также приветствуются.


Некоторый фон:

У меня есть приложение, прослушивающее сокет TCP. Он запускается и завершается с помощью обычного сценария инициализации в стиле System V.

Моя проблема в том, что ему нужно некоторое время для запуска, прежде чем он будет готов к обслуживанию сокета TCP. Это не слишком долго, может быть, всего 5 секунд, но это 5 секунд, когда необходимо выполнить перезапуск в течение рабочего дня. Также важно, чтобы существующие соединения оставались открытыми и нормально завершались.

Причинами перезапуска приложения являются исправления, обновления и тому подобное. К сожалению, я нахожусь в положении, что время от времени мне нужно делать подобные вещи на производстве.


Вопрос:

Я ищу способ аккуратной передачи сокета прослушивания TCP от одного процесса к другому, и в результате получаю лишь долю секунды простоя. Мне бы хотелось, чтобы существующие соединения / сокеты оставались открытыми и завершили обработку в старом процессе, в то время как новый процесс начинает обслуживать новые connectinos.

Есть ли какой-нибудь проверенный способ сделать это с помощью BSD-сокетов? (Бонусные баллы за решение EventMachine.)

Возможно, есть библиотеки с открытым исходным кодом, реализующие это, которые я могу использовать как есть, или использовать в качестве ссылки? (Опять же, не-Ruby и не EventMachine решения также приветствуются!)

Ответы [ 2 ]

8 голосов
/ 05 февраля 2010

Есть несколько способов сделать это без простоев, с соответствующими изменениями в серверной программе.

Одним из них является реализация возможности перезапуска на самом сервере, например, после получения определенного сигнала или другого сообщения. Затем программа выполнит свою новую версию, передав ей номер дескриптора файла сокета прослушивания, например, в качестве аргумента. В этом сокете будет установлен флаг FD_CLOEXEC (по умолчанию), чтобы он был унаследован. Поскольку другие сокеты будут по-прежнему обслуживаться исходным процессом и не должны передаваться новому процессу, флаг должен быть установлен на этих, например, используя fcntl(). После разветвления и исключения нового процесса исходный процесс может продолжить работу и закрыть сокет прослушивания без прерывания работы службы, поскольку новый процесс теперь прослушивает этот сокет.

Альтернативный метод, если вы не хотите, чтобы старый сервер выполнял форк и выполнял сам новый сервер, состоял бы в использовании сокета Unix-домена для связи между старым и новым серверным процессом. , Новый процесс сервера может проверять наличие такого сокета в известном месте в файловой системе при запуске. Если он присутствует, новый сервер подключится к этому сокету и запросит, чтобы старый сервер передал свой сокет прослушивания в качестве вспомогательных данных, используя SCM_RIGHTS. Пример этого приведен в конце cmsg (3) .

1 голос
/ 29 мая 2010

Жан-Пол Кальдероне написал подробную презентацию в 2004 году о целостном решении вашей проблемы с использованием Twisted, включая миграцию сокетов и другие вопросы.

...