0

複数の $pid を使用するスクリプトがあります。そのため、子スポーンの接続が多すぎると、サーバーがハングしてプログラムが実行されません。

サーバーの cron ジョブから自動的に再起動したいのですが、alternatif cPanel を使用しているため実行できません。だから私はそれをスクリプトから自動的に再起動したい。

私はそれを再起動しようとします:

 kill 9, $pid;    
 sleep 60;

出力が表示されます:

Child Spawned : 15945

Killed

しかし、自動実行または再実行する方法がわかりません

4

1 に答える 1

3

フォークごとのワーカープールが必要なようです。サーバー プロセスは、リクエストを処理するために多数の子プロセスを開始し、終了したプロセスを自動的に再起動します。

基本的なテンプレート:

use strict;
use warnings;
use POSIX qw(sigprocmask SIG_BLOCK SIG_UNBLOCK SIGINT SIGTERM WNOHANG);

my $pool_size = 4;  # 4 workers
my %pool;

# When one or more workers die, delete them from the pool
$SIG{CHLD} = sub {
    while ((my $pid = waitpid(-1, WNOHANG)) > 0) {
        delete $pool{$pid};
    }
};

# If a fatal signal is sent to the server, kill all children and exit
for my $sig (qw(INT TERM)) {
    $SIG{$sig} = sub {
        local $SIG{CHLD} = 'IGNORE';
        kill $sig => keys %pool;
        exit;
    };
}

# HUP = restart all workers
$SIG{HUP} = sub {
    print "Caught HUP, restarting workers.\n";
    kill TERM => keys %pool
};

# Set up pool
make_worker() for (1..$pool_size);

# Maintain population
while (1) {
    sleep;  # wait for signal
    while (keys %pool < $pool_size) {
        make_worker();
    }
}

exit;

sub make_worker {
    # Block INT signal during fork, so parent handler is not called
    my $sigset = POSIX::SigSet->new(SIGINT, SIGTERM);
    sigprocmask(SIG_BLOCK, $sigset) or die "Couldn't block signals for fork: $!";
    my $pid = fork;
    die "fork: $!" if !defined $pid;
    if ($pid) {
        sigprocmask(SIG_UNBLOCK, $sigset) or die "Couldn't unblock signals for fork: $!";
        $pool{$pid} = 1;
        return;
    }
    else {
        $SIG{$_} = 'DEFAULT' for qw(INT TERM);
        sigprocmask(SIG_UNBLOCK, $sigset) or die "Couldn't unblock signals for child: $!";

        # Your worker code goes here.

        exit;
    }
}

ループ内の単一のコマンドを単純に再起動するには、試してください。

while(1) {
    system("/path/to/your-command", "--args");
}

コマンドが (何らかの理由で) 終了するとすぐに、再実行されます。システムの終了コードの処理はそれほど単純ではないので、ここでは IPC::System::Simple を使用することをお勧めします。

use IPC::System::Simple qw(system);
use Try::Tiny;

while(1) {
    try { system(...) } 
    catch { "Command failed, restarting: $!" };
}

また、致命的なエラーを示すコマンドの終了が速すぎるかどうかも検出する必要があります。

于 2013-01-25T10:54:07.793 に答える