nja*_*nke 8 perl fastcgi ping nginx
我对nginx和Perl FCGI模块有点问题.我在我的FCGI程序中有一个很长的操作,可能比我用来与FCGI通信的Unix套接字另一端的服务器(或服务器上的用户)一样.我需要程序中的FCGI accept()循环才能在FCGI请求关闭时中断.我尝试安装INT,TERM等信号处理程序,但它们什么都不做,因为nginx和我的程序之间的唯一通信发生在FCGI套接字AFAIK上.
我也尝试了这个但是我无法看到在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;
}
Run Code Online (Sandbox Code Playgroud)
您必须使用FCGI处理.FCGI_ABORT_REQUEST
您不能使用以下内容,因为它们忽略FCGI_ABORT_REQUEST:
您可以使用以下方法来处理FCGI_ABORT_REQUEST:
使用时AnyEvent-FCGI,检查中止的请求与调用一样简单$request->is_active(),但请记住,在处理程序返回is_active()之前,这不会反映请求的真实状态,这意味着您必须尽快on_request返回并以某种方式完成实际工作on_request“并行”(您可能不想使用Perl 线程,而是更类似于延续的东西),以便在您完成冗长的操作时让AnyEvent循环有机会处理任何进一步的请求(包括s)。FCGI_ABORT_REQUEST
我不太熟悉,无法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/plain\nStatus: 200 OK\n\n");
# 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/plain\nStatus: 503 Service Unavailable\n\nBusy!");
}
}
);
AnyEvent->loop;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1716 次 |
| 最近记录: |