我有使用多个 $pid 的脚本。因此,如果子生成的连接过多,我的服务器挂起并且程序无法运行。
我想从我的服务器上的 cron 作业自动重新启动它,但它无法运行,因为我使用了alternatif cPanel。所以我想从它的脚本自动重启它。
我尝试使用以下命令重新启动它:
kill 9, $pid;
sleep 60;
并将显示输出:
Child Spawned : 15945
Killed
但我不知道如何自动运行或重新执行
看起来你想要一个每个分叉的工作池。您的服务器进程启动许多子进程来处理请求,并自动重新启动任何死机。
一个基本模板:
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: $!" };
}
您还应该检测命令是否退出太快,这将表明一个致命错误。