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

Does php automaticly close the TCP connection after every request?

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

我有一个 API 连接器,每个用户每秒调用 1 次来读取消息队列。

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

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

这对 2 个用户来说工作正常,但现在我有 10 个用户使用该系统,这意味着更多 API 呼叫从我的服务器发送。

许多用户 "using the API caller or not" 一直面临超时错误。当我查看 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 caller",大约 200 个用户没有使用。这仅是每秒 10 users/10 API 次调用。

假设 PHP/cURL 自动关闭 TCP 连接,那么我怎么可能只有 10 个人使用 API 达到 5000 个连接?

PHP 数据库连接使用 PDO 基础 class。默认情况下,每次请求完成时它们都会关闭(PHP 脚本完成)。您可以在此处 http://php.net/manual/en/pdo.connections.php.

找到与此相关的更多信息

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

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

您的错误是由于占用了太多连接(OS 只允许这么多)或连接缓冲区溢出造成的。这两个都可以从您的错误消息中推断出来。

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

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

长轮询(也称为彗星)意味着您的服务器不会立即响应请求,而是等待直到有消息要发送或达到超时。这样更好,因为您现在的请求变少了。但它仍然不可扩展,因为在服务器上你将继续敲击数据库。

Websockets 就是您要找的。您的浏览器连接到 websocket 服务器,并永远保持连接。这是一个双向沟通渠道,双方始终可用。还有两件事要知道:

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

ratchet 视为基于 php 的 websocket 守护程序,并将 Autobahn.js 视为客户端。

编辑: Ratchet 不幸的是不再维护。我切换到 node.js.