PHP作为FastCGI应用程序(php-cgi)运行 - 如何发出并发请求? [英] PHP running as a FastCGI application (php-cgi) - how to issue concurrent requests?

查看:316
本文介绍了PHP作为FastCGI应用程序(php-cgi)运行 - 如何发出并发请求?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:更新 - 向下卷动

编辑2:更新 - 问题已解决 >



一些背景信息



我用Java编写自己的网络服务器,的日子我问了如何确切Apache接口与PHP,所以我可以实现PHP支持。我学习了FastCGI是最好的方法(因为mod_php不是一个选项)。所以我看了FastCGI协议规范,并设法为我的服务器写一个工作的FastCGI包装。我测试了phpinfo()和它的工作,事实上所有的PHP函数似乎工作很好(发布数据,会话,日期/时间等)。



webserver能够同时服务请求(即,user1可以在user2请求some_large_binary_file.zip的同时检索file1.html),它通过为每个用户请求生成一个新的Java线程(在完成时终止或者与客户端的用户连接取消)。



但是,它不能同时处理2个(或更多)FastCGI请求。它做的是,它排队他们,所以当请求1后立即完成它开始处理请求2.我测试这个与2 PHP页面,一个包含sleep(10)和其他phpinfo()。



我如何处理多个请求,因为我知道它可以做(IIS下的PHP运行为FastCGI,它可以处理多个请求很好)。



一些更多信息:



我在窗口下编码,我的批处理文件用于执行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段) a>)。



我没有测试这个,但我怎么实现呢?我认为我需要某种FastCGI Java线程,其中包含一些类的地图和一个静态函数,我可以使用它来添加请求。然后在Thread的run()函数中,它会有一个while循环,并且对于每个循环,它将检查Map是否包含新的请求,如果是,则会为它们分配一个请求ID并将它们写入FastCGI流。然后等待输入等等,你可以看到这变得太复杂了。



有没有人知道这样做的正确方法?或任何想法?非常感谢。



注意,如果需要,我可以提供我的FastCGI包装程序的代码。

$ b


更新



基本上,我下载nginx并将其设置为使用PHP作为FastCGI应用程序,它也遭受与我的服务器相同的问题。它无法处理并发PHP请求。这让我相信我的代码其实是正确的。所以,PHP的错误或我没有正确设置。也许是因为我使用Windows,因为一些lighttpd用户声称Windows无法正确处理FastCGI(这没有什么意义)。我会很快安装Linux,并报告任何进度。

解决方案

好,我设法找到问题的原因。这不是我的代码。它是PHP,它不能产生额外的php cgi的Windows下运行作为FastCGI模式,在Linux下它的工作完美,我只是指向我的服务器到我的linux盒IP,它没有问题的并发FCGI请求。 Sucks,但我想这是它的方式...



之后,我深入了解PHP源代码,发现响应PHP_FCGI_CHILDREN的代码部分已被#ifndef WIN32封装所以开发人员必须知道


的问题

EDIT: Update - scroll down
EDIT 2: Update - problem solved


Some background information:

I'm writing my own webserver in Java and a couple of days ago I asked on SO how exactly Apache interfaces with PHP, so I can implement PHP support. I learnt that FastCGI is the best approach (since mod_php is not an option). So I have looked at the FastCGI protocol specification and have managed to write a working FastCGI wrapper for my server. I have tested phpinfo() and it works, in fact all PHP functions seem to work just fine (posting data, sessions, date/time, etc etc).

My webserver is able to serve requests concurrently (ie user1 can retrieve file1.html at the same time as user2 requesting some_large_binary_file.zip), it does this by spawning a new Java thread for each user request (terminating when completed or user connection with client is cancelled).

However, it cannot deal with 2 (or more) FastCGI requests at the same time. What it does is, it queues them up, so when request 1 is completed immediately thereafter it starts processing request 2. I tested this with 2 PHP pages, one contains sleep(10) and the other phpinfo().

How would I go about dealing with multiple requests as I know it can be done (PHP under IIS runs as FastCGI and it can deal with multiple requests just fine).

Some more info:

I am coding under windows and my batch file used to execute php-cgi.exe contains:

set PHP_FCGI_CHILDREN=8
set PHP_FCGI_MAX_REQUESTS=500
php-cgi.exe -b 9000

But it does not spawn 8 children, the service simply terminates after 500 requests.

I have done research and from Wikipedia:

Processing of multiple requests simultaneously is achieved either by using a single connection with internal multiplexing (ie. multiple requests over a single connection) and/or by using multiple connections

Now clearly the multiple connections isn't working for me, as everytime a client requests something that involves FastCGI it creates a new socket to the FastCGI application, but it does not work concurrently (it queues them up instead).

I know that internal multiplexing of FastCGI requests under the same connection is accomplished by issuing each unique FastCGI request with a different request ID. (also see the last 3 paragraphs of 'The Communication Protocol' heading in this article).

I have not tested this, but how would I go about implementing that? I take it I need some kind of FastCGI Java thread which contains a Map of some sort and a static function which I can use to add requests to. Then in the Thread's run() function it would have a while loop and for every cycle it would check whether the Map contains new requests, if so it would assign them a request ID and write them to the FastCGI stream. And then wait for input etc etc, As you can see this becomes too complicated.

Does anyone know the correct way of doing this? Or any thoughts at all? Thanks very much.

Note, if required I can supply the code for my FastCGI wrapper.


Update:

Basically, I downloaded nginx and set it up to use PHP as a FastCGI application and it too suffered from the same problem as my server. It could not handle concurrent PHP requests. This is leads me to believe my code is in fact correct. So something is wrong with PHP or I am not setting it up correctly. Maybe it is because I am using Windows because some lighttpd users claim Windows can't handle FastCGI properly (this doesn't make much sense). I'll install Linux sometime soon and report any progress with that.

解决方案

Okay, I managed to find the cause of the problem. It wasn't my code at all. It's PHP, it cannot spawn additional php-cgi's under Windows when running as FastCGI mode, under Linux it works perfectly, I simply pointed my server to my linux box IP and it had no problems with concurrent FCGI requests. Sucks, but I guess that's the way it is...

I did look deeper into the PHP source code after that and found that the section of code which responds to PHP_FCGI_CHILDREN has been encapsulated by #ifndef WIN32 So the developers must be aware of the issue

这篇关于PHP作为FastCGI应用程序(php-cgi)运行 - 如何发出并发请求?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆