Perl Net::Горячее развертывание сервера

Я использую Net::Server::Prefork для запуска TCP-сервера. Процедура запуска выглядит следующим образом:

use 5.10.1;
use strict;
use warnings;
use parent 'Net::Server::Fork';

        Dispatcher->run(
            'host'            => $host                                   || '*',
            'port'            => $port                                   || 7000,
            'ipv'             => '*',
            'log_level'       => $main::config{'backend.loglevel'}       || 0,
            'log_file'        => $main::config{'backend.logfile'}        || undef,
            'pid_file'        => $main::config{'backend.pidfile'}        || undef,
            'user'            => $main::config{'backend.user'}           || 'nobody',
            'group'           => $main::config{'backend.group'}          || 'nogroup',
            'max_servers'     => $main::config{'backend.maxconnections'} || 3,
            'background'      => !$main::config{'backend.foreground'}    || undef,
            'allow'           => $main::config{'ip'}                     || '.*',
            'reverse_lookups' => 1,
        );

Диспетчер использует эту функцию для обработки запросов:

sub process_request {
    eval {
        local $SIG{'ALRM'} = sub { die "Timed Out!\n" };
        my $previous_alarm = alarm($timeout);
        my @args;
        {
            my $command =  <STDIN>;
            @args = split /\s+/, $command;
            alarm($timeout);
        }

        alarm(($main::config{'timeout'} + 5) || 185);
        {
            Dispatcher::main(@args);
        }
        alarm($previous_alarm);
    };
};

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

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

Любые идеи приветствуются!


person Marcus    schedule 18.02.2015    source источник


Ответы (1)


Вы пытались использовать параметр конфигурации leave_children_open_on_hup и перезапустить сервер с помощью сигнала HUP? [рецепт для linux/unix]
Это должно работать в соответствии с документацией.

Перезапуск Net::Server

person AnFi    schedule 18.02.2015
comment
Нет. По общему признанию, я пропустил это, так что спасибо, что указали на это. Я попробую это решение и вернусь, как только оно сработает. - person Marcus; 18.02.2015
comment
Я добавил leave_children_open_on_hup в конфигурацию, и в основном это помогает. Однако запросы в обработке останавливаются. strace показывает, что они застревают на системном вызове чтения. В любом случае, я принял ваше решение, но мне осталось немного покопаться в том, почему время чтения истекло. - person Marcus; 19.02.2015