我在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连接?
答案 0 :(得分:3)
问题在于您的应用程序架构。 Ajax轮询不可扩展。
短轮询(您所做的)不可扩展,因为它只会使服务器充满请求。您每秒和每个用户有一个请求。这为10个用户每秒提供10个请求。您针对您的服务器设置了DoS攻击!
长轮询(也称为comet)意味着您的服务器不会立即响应请求,而是等待发送消息或直到达到超时。这样更好,因为您现在的请求较少。但它仍然无法扩展,因为在服务器上,您将继续使用数据库。
您正在寻找Websockets 。您的浏览器连接到websocket服务器,并永久保持连接。它是双向通信通道,双方始终可用。还有两件事要知道:
将ratchet
视为基于php的websocket deamon,并将其作为客户端的Autobahn.js。
编辑 Ratchet
已不再维护。我切换到node.js。
答案 1 :(得分:1)
PHP数据库连接使用PDO基类。默认情况下,每次请求完成时它们都会关闭(PHP脚本完成)。您可以在http://php.net/manual/en/pdo.connections.php找到与此相关的更多信息。
您可以强制您的数据库连接是持久的,如果您要经常重复使用数据库连接,这通常是有益的。
Apache(我假设)和其他服务器一样。它不断地在给定端口上侦听传入连接。它确定连接读取请求发出响应,然后关闭连接。
您的错误是由多达几个连接引起的(操作系统只允许这么多)或者溢出缓冲区以进行连接。这些都可以从您的错误消息中推断出来。