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

标签 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 日志时,我看到了这个 fatal error

[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 连接,那么我如何才能达到只有 10 个使用 API 的人的 5000 个连接?

最佳答案

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

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

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

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

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

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

编辑 Ratchet 很遗憾不再维护。我切换到 node.js。

关于php - php 会在每次请求后自动关闭 TCP 连接吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32015218/

相关文章:

php - 仅忽略 PHPUnit 中的特定警告(如 E_STRICT 或 E_DEPRECATED)

php - 最简单的 PHP 表单验证库?

php - 移动媒体 wiki 目录后出现 500 服务器错误

python - socket.recvmsg 忽略 ancbufsize、辅助数据

php - 在mysql数据库中保存格式化文本

php - 为什么在不同的编程语言中 0.5 mod 0.1 的结果不同?

apache - 使用 $10、$11、$12 等重写规则

regex - .htaccess 文件访问

Linux 和 I/O 完成端口?

php - PHP socket_read转换为int