Wal*_*jad 9 php concurrency fastcgi
编辑:更新 - 向下滚动
编辑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
Run Code Online (Sandbox Code Playgroud)
但它不会产生8个孩子,该服务只是在500个请求后终止.
我从维基百科做过研究:
通过使用具有内部多路复用的单个连接(即,通过单个连接的多个请求)和/或通过使用多个连接来实现同时处理多个请求
现在很明显,多个连接对我来说不起作用,因为每次客户端请求涉及FastCGI的内容时,它都会为FastCGI应用程序创建一个新的套接字,但它并不能同时工作(而是将它们排队等).
我知道在相同连接下对FastCGI请求进行内部多路复用是通过发出具有不同请求ID的每个唯一FastCGI请求来完成的.(另见的"通信协议"标题中的最后3段这篇文章).
我没有对此进行过测试,但我将如何实现呢?我认为我需要某种FastCGI Java线程,它包含某种类型的Map和一个静态函数,我可以使用它来添加请求.然后在Thread的run()函数中它将有一个while循环,并且对于每个循环,它将检查Map是否包含新请求,如果是,它将为它们分配请求ID并将它们写入FastCGI流.然后等待输入等等,你可以看到这变得太复杂了.
有谁知道这样做的正确方法?还是有任何想法?非常感谢.
注意,如果需要,我可以提供我的FastCGI包装器的代码.
更新:
基本上,我下载了nginx并将其设置为使用PHP作为FastCGI应用程序,它也遇到了与我的服务器相同的问题.它无法处理并发的PHP请求.这让我相信我的代码实际上是正确的.所以PHP出了问题,或者我没有正确设置它.也许是因为我使用的是Windows,因为一些lighttpd用户声称Windows无法正常处理FastCGI(这没有多大意义).我将很快安装Linux并报告任何进展.
好的,我设法找到了问题的原因.这根本不是我的代码.这是PHP,它在Windows下作为FastCGI模式运行时无法生成额外的php-cgi,在Linux下运行完美,我只是将我的服务器指向我的linux机箱IP并且它没有并发FCGI请求的问题.很糟糕,但我想这就是它的方式......
之后我深入研究了PHP源代码,发现响应PHP_FCGI_CHILDREN的代码部分已被#ifndef WIN32封装,因此开发人员必须意识到这个问题