php是否在每次请求后自动关闭TCP连接?

时间:2015-08-14 17:00:51

标签: php apache sockets tcp windows-server-2008-r2

我在Windows Server 2008 R2上运行Apache 2.4 / PHP 5.6.13。

我有一个API连接器,每个用户每秒进行1次呼叫以读取消息队列。

我正在使用setInterval(...., 1000)向执行实际API调用的处理程序发出ajax请求。

处理程序对API服务进行cURL调用以读取消息传递队列。

这适用于2个用户,但现在我有10个用户使用该系统,这意味着从我的服务器发送了更多的API调用。

许多用户"是否使用API​​调用者"一直面临超时错误。当我查看php日志时,我看到了这个致命的错误

[14-Aug-2015 16:37:08 UTC] PHP Fatal error:  Uncaught exception 'PDOException' with message 'SQLSTATE[HY000] [2002] An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full.

我对这个问题进行了研究,发现它不是一个SQL错误,而是一个Windows错误。 It is explained here.

在我看来,我需要编辑Windows注册表来解决问题explained here,但我不想在生产服务器上专门触摸Windows注册表。

我的问题是PHP是否保持TCP连接打开,还是在每次请求后关闭它?

我有10个用户使用" API来电"还有大约200个不是。这只是每秒10个用户/ 10个API调用。

假设PHP / cURL自动关闭TCP连接,那么我怎样才能使用API​​从10个人那里获得5000连接?

2 个答案:

答案 0 :(得分:3)

问题在于您的应用程序架构。 Ajax轮询不可扩展。

短轮询(您所做的)不可扩展,因为它只会使服务器充满请求。您每秒和每个用户有一个请求。这为10个用户每秒提供10个请求。您针对您的服务器设置了DoS攻击!

长轮询(也称为comet)意味着您的服务器不会立即响应请求,而是等待发送消息或直到达到超时。这样更好,因为您现在的请求较少。但它仍然无法扩展,因为在服务器上,您将继续使用数据库。

您正在寻找

Websockets 。您的浏览器连接到websocket服务器,并永久保持连接。它是双向通信通道,双方始终可用。还有两件事要知道:

  • 你需要另一个服务器用于websockets,Apache无法做到这一点。
  • 在服务器端,您需要一个事件系统。锤击数据库不是解决方案。

ratchet视为基于php的websocket deamon,并将其作为客户端的Autobahn.js。

遗憾的是,

编辑 Ratchet已不再维护。我切换到node.js。

答案 1 :(得分:1)

PHP数据库连接使用PDO基类。默认情况下,每次请求完成时它们都会关闭(PHP脚本完成)。您可以在http://php.net/manual/en/pdo.connections.php找到与此相关的更多信息。

您可以强制您的数据库连接是持久的,如果您要经常重复使用数据库连接,这通常是有益的。

Apache(我假设)和其他服务器一样。它不断地在给定端口上侦听传入连接。它确定连接读取请求发出响应,然后关闭连接。

您的错误是由多达几个连接引起的(操作系统只允许这么多)或者溢出缓冲区以进行连接。这些都可以从您的错误消息中推断出来。