编辑:更新 - 向下滚动
编辑2:更新 - 问题已解决
我正在用Java编写我自己的网络服务器,几天前我问到Apache究竟是如何与PHP接口的,所以我可以实现PHP支持。我了解到FastCGI是最好的方法(因为mod_php不是一个选项)。所以我查看了FastCGI协议规范,并设法为我的服务器编写了一个可用的FastCGI包装器。我已经测试了phpinfo()并且它可以工作,实际上所有的PHP函数似乎都运行得很好(发布数据,会话,日期/时间等)。
我的网络服务器能够同时处理请求(即user1可以在user2请求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个请求后终止。
我已经从Wikipedia完成了研究:
处理多个请求 同时通过 使用单一连接 内部多路复用(即多重 通过单个连接请求) 和/或使用多个连接
现在显然多个连接对我不起作用,因为每次客户端请求涉及FastCGI的内容时,它都会为FastCGI应用程序创建一个新套接字,但它不能同时工作(而是将它们排队等)。
我知道在相同连接下对FastCGI请求进行内部多路复用是通过发出具有不同request ID的每个唯一FastCGI请求来完成的。 (另请参阅this article中“通信协议”标题的最后3段。
我没有对此进行测试,但我将如何实施呢?我认为我需要某种FastCGI Java线程,它包含某种类型的Map和一个静态函数,我可以使用它来添加请求。然后在Thread的run()函数中它将有一个while循环,并且对于每个循环,它将检查Map是否包含新请求,如果是,它将为它们分配请求ID并将它们写入FastCGI流。然后等待输入等等,你可以看到这变得太复杂了。
有谁知道这样做的正确方法?还是有任何想法?非常感谢。
注意,如果需要,我可以提供我的FastCGI包装器的代码。
更新:
基本上,我下载了nginx并将其设置为使用PHP作为FastCGI应用程序,它也遇到了与我的服务器相同的问题。它无法处理并发的PHP请求。这让我相信我的代码实际上是正确的。所以PHP出了问题,或者我没有正确设置它。也许是因为我使用的是Windows,因为一些lighttpd用户声称Windows无法正常处理FastCGI(这没有多大意义)。我将很快安装Linux并报告任何进展。
答案 0 :(得分:7)
好的,我设法找到了问题的原因。这根本不是我的代码。这是PHP,它在Windows下作为FastCGI模式运行时无法生成额外的php-cgi,在Linux下运行完美,我只是将我的服务器指向我的linux机箱IP并且它没有并发FCGI请求的问题。很糟糕,但我想这就是它的方式......
之后我深入研究了PHP源代码,发现响应PHP_FCGI_CHILDREN的代码部分已经被#ifndef WIN32封装了所以开发人员必须意识到这个问题
答案 1 :(得分:2)
嗨,这有点晚了,我在windows上为php-cgi.exe写了一个spawner,不完美,但它可能就是你所需要的。请在here处查看。
答案 2 :(得分:2)
re:spawn-php python脚本......
非常感谢@nosam帮助 对于那些想要让它快速工作的人,你需要以下(如果是64位系统)
ActivePython-2.7.2.5-win64-x64.msi
pywin32-217.win-amd64-py2.7.exe
ActivePython在他们的www上没有旧版本的这些,所以你需要做一些谷歌搜索才能找到一个工作镜像(那里有很多)
从bitbucket下载src后,您可能需要编辑spawn-php.py(以修复选项卡间距),因为bit-bucket似乎弄乱了文件中的选项卡,导致它无法运行。
使用nginx + fast-cgi为繁忙的小型Windows网站节省了我的一天。
谢谢你的伴侣!