2

我提出的这个问题促使我探索将我的 FastCGI 脚本直接连接到 NGINX,而不是使用 Apache 的反向代理。我使用我在网上找到的一些代码成功地修改了我的 FastCGI 脚本以作为守护进程运行:

my $s = FCGI::OpenSocket(':9000',20);
my $request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%ENV, $s);

# Remaining code stays just as it does when using with Apache's mod_fcgid
while($request->Accept() >= 0) {
     # Call core app subroutines.
}

它可以工作,但据我所知,这与 mod_fcgid 相比有一个明显的缺点:我有一个正在运行的进程,它一次处理一个请求,如果该进程终止,则没有任何东西可以启动它。在 Stack Overflow 上引用了正确剥离工作人员的代码,但所引用的网站不可避免地似乎已经离线,就像 FastCGI 自己的网站一样。

所以,我试图弄清楚我需要添加什么,并且——请原谅双关语——弄清楚我是否需​​要在这条路上分叉。如果我正确理解我的问题,以下是我正在尝试考虑的选项:

  1. 直接实现某种分叉机制,理想情况下,它似乎应该(1)将请求扔给一个进程/线程/工作者——也许一个可以为多个请求保持活动状态——并继续为下一个请求做好准备请求和(2)足够独立于工人,如果工人出了问题,它不会关闭整个系统,直到我抓住它并重新启动主进程(例如自动重启进程)。如果这可以简单可靠地完成,这似乎具有巨大的吸引力,因为代码已经与 FastCGI 一起使用。

  2. 放弃直接 FastCGI 并转换为 PSGI 并使用应用程序服务器来处理这些事情。鉴于我正在使用 Perl,我猜 Starman 是合乎逻辑的选择,尽管我一直在阅读 uwsgi 的 PSGI 支持,它在“暴君皇帝”模式下听起来几乎是理想的,它可以运行具有不同权限的进程,自动重新启动丢失的进程等

选项 1 看起来很有趣,因为它需要对我现有的代码进行最少的修改,而且在没有 FastCGI 的情况下启动的 FastCGI 脚本仍然像普通的 CGI 脚本一样工作。(当流量非常低的网站使用此代码时,我不会在 FastCGI 下运行此代码)。

不过,选项 2 感觉它可能更“现代”。例如,至少 PSGI 文档似乎仍然在线,并且使用 Starman 或 uwsgi 似乎他们可以处理我需要的背景内容,这可能比我自己编写系统更好。缺点:我的代码需要两个启动脚本:一个供启用 PSGI 的站点使用,另一个用于仍在 CGI 中运行的站点。

更新:继续探索选项 1,我通读了这个关于 Perl 的教程,fork()这似乎有点相关。如果我选择选项 1,使用fork中断每个 FastCGI 请求是一个好方法吗?我认为我将面临分叉爆炸的风险,尽管如果我跟踪分叉的数量并发布wait() if ($forks > 10);,也许这将是一种安全的方法?(或者也许Parallel::ForkManager用来监视该过程。)或者使用类似的东西Thread::Queue并将FastCGI请求对象传递给已经可靠建立的线程集会更安全和/或更有效吗?似乎有很多我可能会忽略的陷阱,然后让我回到是否应该选择选项 2。

4

0 回答 0