从/ etc / inittab重新启动Perl脚本(套接字守护进程)

我在高峰时期运行了一个大约500名用户的小型多人纸牌游戏 :

截图

客户端在Flash中,服务器在Perl中。

Perl服务器绑定到8080端口,即只能启动1个实例(重要细节)。

Perl服务器轮询()的TCP套接字和叉只有一次 – 在启动时通过调用此方法:

sub daemonize { die "Can not fork: $!\n" unless defined (my $child = fork()); # the parent should die exit 0 if $child; setsid(); open(STDIN, '</dev/null'); open(STDOUT, '>/tmp/pref.txt'); open(STDERR, '>&STDOUT'); chdir('/'); umask(0); } .... $tcpSocket = IO::Socket::INET->new(Proto => 'tcp', LocalPort => 8080, Listen => SOMAXCONN, ReuseAddr => 1, ); die "Can not create listening TCP socket: $!\n" unless defined $tcpSocket; 

它运行在CentOS 5.6 Linux / 64位,PostgreSQL 8.4.8和Perl 5.8.8上。

由于我的预算很小,而且已经有了足够的麻烦,所以我希望尽可能使用更less的软件 – 以便我可以快速更换主机或重新安装便宜的服务器。 这就是为什么我例如只是login到/tmp/pref.txt而不是安装syslog-ng。 这就是为什么我想用/ etc / inittab来重启我的Perl守护进程

我的Perl守护进程大多运行稳定,但约。 一个星期一次它可以与一个崩溃

 May 29 11:06:46 myhost kernel: pref.pl[3113]: segfault at 00007fffa21e6fd8 rip 0000003cce274460 rsp 00007fffa21e6fd0 error 6 

由于我厌倦了手动重新启动服务器,我试图将其添加到/ etc / inittab中:

 pref:3:respawn:/bin/su -c '/usr/local/pref/pref.pl' nobody 

(我已经添加了一个夜间cronjob到“pkill pref.pl”,希望能够刷新perl)。

不幸的是,这不能按预期的方式工作 – 在/ var / log / messages中,我发现脚本被一次又一次启动:

 Jun 2 18:55:56 myhost init: Id "pref" respawning too fast: disabled for 5 minutes Jun 2 19:00:58 myhost init: Id "pref" respawning too fast: disabled for 5 minutes Jun 2 19:06:02 myhost init: Id "pref" respawning too fast: disabled for 5 minutes 

我在这里做错了什么? 我希望能够在这里使用/ etc / inittab,因为我记得几年前在工作时也使用它(也用Perl守护进程),它运行良好,然后…

谢谢! 亚历克斯

更新:

我的游戏没有崩溃,Perl解释器(但不是经常,每周一次)。

我的问题是关于如何 从/ etc / inittab 运行一个Perl守护进程 (即一个开始fork一次,然后绑定到一个TCP端口的Perl脚本)

只需从代码中删除fork()。 到目前为止,你已经写了一段代码,你想从控制台join并在后台运行。 但是,当从inittab运行进程时,他们需要保持连接。 如果你删除fork(),它将保持连接到init,init将能够正确地监视/启动/停止/重新启动

我不能说你的inittab解决scheme,希望别人可以,但我想build议你看看“File :: Pid”作为添加到你的脚本 – 在守护进程调用之后(这很重要 – 你的进程ID后叉改变)。

 use File::Pid; my $pidfile = File::Pid->new({ file => '/var/run/myprogram.pid', pid => $$, }); if ( my $num = $pidfile->running ) { exit; } $pidfile->write; 

这给你一些东西 – 一个确保你不会同时运行它的两个副本(你说的是一个大问题),它也可以让你安全地调用这个程序,只要你想提供一个简单的keepalive。 只要每10分钟从cron调用一次你的代码,如果它正在运行,它就什么都不做,或者如果它停止了,它就会重启。