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 回答