如何使用Perl FCGI杀死?
我在使用nginx和Perl FCGI模块时遇到了一些问题.我在我的FCGI程序中有一个很长的操作,可能比我用来与FCGI通信的Unix套接字另一端的服务器(或服务器上的用户)一样.我需要程序中的FCGI accept()循环,以便在FCGI请求关闭时中断.我尝试安装INT,TERM等信号处理程序,但它们什么都不做,因为nginx和我的程序之间的唯一通信发生在FCGI套接字AFAIK上.
我也尝试过this但是我无法看到在Perl中使用FCGI模块通过FCGI套接字向nginx发送原始数据或从nginx发送原始数据.有没有办法在不修改FCGI模块的情况下进行“ping”功能? 基本问题是我的程序不知道nginx是否已终止FCGI请求. 例: #!/usr/bin/perl -w use strict; use FCGI; my $fcgi_socket = FCGI::OpenSocket( '/tmp/test.socket',100000 ); my $request = FCGI::Request(*STDIN,*STDOUT,*STDERR,%ENV,$fcgi_socket); REQUEST: while($request->Accept() >= 0) { #begin handling request my $result = ''; while (1) { #or select(),etc if (somehow check whether the fcgi $request is still live) { next REQUEST; } #check for results,set $result if done } print $result; } 解决方法
您必须使用处理FCGI_ABORT_REQUEST的FCGI实现.
您不能使用以下内容,因为它们忽略FCGI_ABORT_REQUEST: > FCGI <=v0.69(您目前正在使用的那个?) 您可以使用以下内容来处理FCGI_ABORT_REQUEST: > Vitaly Kramskikh’s AnyEvent-FCGI 使用AnyEvent-FCGI时,检查中止请求就像调用$request-> is_active()一样简单,但请记住,在on_request处理程序返回之前,is_active()不会反映请求的真实状态,这意味着你必须尽快从on_request返回并以某种方式“并行”实际工作(你可能不想使用Perl threads,但更类似于continuations),以便为AnyEvent循环提供处理任何机会的机会在您完成冗长的操作时,还有其他请求(包括FCGI_ABORT_REQUESTs). 我对AnyEvent不太熟悉,无法确定是否有更好的方法可以做到这一点,但这是我的观点,下面是一个开始: use AnyEvent; use AnyEvent::FCGI; my @jobs; my $process_jobs_watcher; sub process_jobs { # cancel aborted jobs @jobs = grep { if ($_->[0]->is_active) { true } else { # perform any job cleanup false } } @jobs; # any jobs left? if (scalar(@jobs)) { my $job = $jobs[0]; my ( $job_request,$job_state ) = @$job; # process another chunk of $job # if job is done,remove (shift) from @jobs } else { # all jobs done; go to sleep until next job request undef $process_jobs_watcher; } } my $fcgi = new AnyEvent::FCGI( port => 9000,on_request => sub { my $request = shift; if (scalar(@jobs) < 5) { # set your own limit # accept request and send back headers,HTTP status etc. $request.print_stdout("Content-Type: text/plainnStatus: 200 OKnn"); # This will hold your job state; can also use Continutiy # http://continuity.tlt42.org/ my $job_state = ...; # Enqueue job for parallel processing: push @jobs,[ $request,$job_state ]; if (!$process_jobs_watcher) { # If and only if AnyEvent->idle() does not work,# use AnyEvent->timer() and renew from process_jobs $process_jobs_watcher = AnyEvent->idle(cb => &;process_jobs); } } else { # refuse request $request.print_stdout("Content-Type: text/plainnStatus: 503 Service UnavailablennBusy!"); } } ); AnyEvent->loop; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |