编辑:更新 - 向下滚动
编辑2:更新-问题已解决
Some background information:
我正在用 Java 编写自己的网络服务器,几天前我询问 Apache 与 PHP 的接口到底如何,这样我就可以实现 PHP 支持。我了解到 FastCGI 是最好的方法(因为 mod_php 不是一个选项)。因此,我查看了 FastCGI 协议规范,并设法为我的服务器编写了一个可用的 FastCGI 包装器。我已经测试了 phpinfo() 并且它有效,事实上所有 PHP 函数似乎都工作得很好(发布数据、会话、日期/时间等)。
我的网络服务器能够同时服务请求(即用户1可以在用户2请求some_large_binary_file.zip的同时检索file1.html),它通过为每个用户请求生成一个新的Java线程(在完成或用户与客户端的连接时终止)来实现这一点取消)。
但是,它无法同时处理 2 个(或更多)FastCGI 请求。它的作用是,将它们排队,因此当请求 1 完成后,它立即开始处理请求 2。我用 2 个 PHP 页面对此进行了测试,一个包含 sleep(10),另一个包含 phpinfo()。
我将如何处理多个请求,因为我知道它可以完成(IIS 下的 PHP 作为 FastCGI 运行,它可以很好地处理多个请求)。
更多信息:
我在 Windows 下编码,用于执行 php-cgi.exe 的批处理文件包含:
set PHP_FCGI_CHILDREN=8
set PHP_FCGI_MAX_REQUESTS=500
php-cgi.exe -b 9000
但它不会产生 8 个子级,服务在 500 个请求后就会终止。
我已经做了研究并从维基百科:
处理多个请求
同时通过以下方式实现
使用单个连接
内部复用(即多个
通过单个连接的请求)
和/或通过使用多个连接
现在显然多个连接对我不起作用,因为每次客户端请求涉及 FastCGI 的内容时,它都会为 FastCGI 应用程序创建一个新套接字,但它不能同时工作(而是将它们排队)。
我知道同一连接下 FastCGI 请求的内部多路复用是通过使用不同的地址发出每个唯一的 FastCGI 请求来完成的。请求ID。
(另请参阅“通信协议”标题的最后 3 段本文).
我还没有测试过这一点,但我将如何实施呢?我认为我需要某种 FastCGI Java 线程,其中包含某种 Map 和一个静态函数,我可以用它来添加请求。然后,在线程的 run() 函数中,它将有一个 while 循环,并且对于每个循环,它将检查 Map 是否包含新请求,如果包含,它将为它们分配一个请求 ID 并将它们写入 FastCGI 流。然后等待输入等等,正如你所看到的,这变得太复杂了。
有谁知道这样做的正确方法?或者有什么想法吗?非常感谢。
请注意,如果需要,我可以提供 FastCGI 包装器的代码。
Update:
基本上,我下载了 nginx 并将其设置为使用 PHP 作为 FastCGI 应用程序,它也遇到了与我的服务器相同的问题。它无法处理并发 PHP 请求。这让我相信我的代码实际上是正确的。所以 PHP 有问题或者我没有正确设置它。也许是因为我使用的是Windows,因为一些lighttpd用户声称Windows无法正确处理FastCGI(这没有多大意义)。我将很快安装 Linux 并报告任何进展。