用于处理服务器端事件的PHP服务器导致Apache连接太多

时间:2015-12-10 21:02:26

标签: javascript php html5 apache server-sent-events

我有PHP服务器进程响应服务器端事件,将其视为仪表板更新脚本。

它基本上每隔几秒就将数据(JSON)发送到一个仪表板页面,该页面利用SSE(服务器端事件)来显示仪表板。问题是一段时间之后PHP进程终止,但重新生成(这是SSE协议的一部分),这很好,但不知怎的,它让我的网络服务器在几个小时后看起来像这样......

 PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
 2954 root       20   0 22372  2140  1244 R  1.0  0.1  0:00.06 htop
 2952 root       20   0 70160  3584  2684 S  1.0  0.2  0:00.05 sshd: root [priv]
    1 root       20   0 10648   692   648 S  0.0  0.0  1:33.93 init [2]
  378 root       20   0 21348  1044   772 S  0.0  0.1  0:00.28 udevd --daemon
 1164 www-data   20   0  354M 16616  6200 S  0.0  0.8  0:00.00 /usr/sbin/apache2 -k start
 1165 www-data   20   0  354M 16616  6200 S  0.0  0.8  0:03.32 /usr/sbin/apache2 -k start
 1077 www-data   20   0  354M 16616  6200 S  0.0  0.8  0:03.35 /usr/sbin/apache2 -k start
 1115 www-data   20   0  356M 19704  6404 S  0.0  1.0  0:00.00 /usr/sbin/apache2 -k start
 1116 www-data   20   0  356M 19704  6404 S  0.0  1.0  0:02.87 /usr/sbin/apache2 -k start
 1079 www-data   20   0  356M 19704  6404 S  0.0  1.0  0:02.93 /usr/sbin/apache2 -k start
 1542 www-data   20   0  292M 18796  6516 S  0.0  0.9  0:00.00 /usr/sbin/apache2 -k start
 1543 www-data   20   0  292M 18796  6516 S  0.0  0.9  0:01.93 /usr/sbin/apache2 -k start
 1455 www-data   20   0  292M 18796  6516 S  0.0  0.9  0:01.98 /usr/sbin/apache2 -k start
 1811 www-data   20   0  360M 26516 12636 S  0.0  1.3  0:00.00 /usr/sbin/apache2 -k start
 1812 www-data   20   0  360M 26516 12636 S  0.0  1.3  0:01.87 /usr/sbin/apache2 -k start
 1669 www-data   20   0  360M 26516 12636 S  0.0  1.3  0:01.98 /usr/sbin/apache2 -k start
 1713 www-data   20   0  354M 13160  2992 S  0.0  0.6  0:00.00 /usr/sbin/apache2 -k start
 1714 www-data   20   0  354M 13160  2992 S  0.0  0.6  0:02.06 /usr/sbin/apache2 -k start
 1672 www-data   20   0  354M 13160  2992 S  0.0  0.6  0:02.06 /usr/sbin/apache2 -k start
 1879 www-data   20   0  356M 20292  6988 S  0.0  1.0  0:00.00 /usr/sbin/apache2 -k start
 1880 www-data   20   0  356M 20292  6988 S  0.0  1.0  0:01.19 /usr/sbin/apache2 -k start
 .. many more 

首先,我知道PHP不是编写这些长期运行(守护进程)背景服务的理想语言,而NodeJS之类的东西会更合适,但在开发的这一点上,它并不是实际重写一切(即没有预算)。

所以我的问题是有一些方法可以阻止Apache为这些特定的PHP请求生成新的连接,或者以某种方式重新使用特定的进程来维护这个PHP脚本。本质上,将请求缓存到单个Apache进程时SEE请求发生...谢谢

2 个答案:

答案 0 :(得分:1)

默认情况下,在JavaScript中,服务器端事件内置了错误处理。此错误处理的一部分包括在关闭SSE事件句柄(故意或意外)时重新连接到服务器。默认重新连接时间约为3秒。在根据此站点的大多数浏览器实现中:HTML 5 Rocks

根据链接,服务器在其回复中可以指定客户端在尝试重新连接之前应等待的重试时间,如果您希望覆盖约3秒的默认值。下面是一个例子:

retry: 10000\n
data: hello world\n\n

这对您有何帮助?

您可能想知道这对您有何帮助。好问题。正如您所知,Apache并非真正构建用于SSE或套接字事件等持久性连接。为了在PHP中容纳这一点,每次发回数据回复时,都可以指定retry标题,如上所示。然后在脚本调用结束时exit。 PHP将完成,Apache将关闭连接,但一旦错误处理重新连接执行,SSE链将继续。

绝不是最优雅的解决方案。实际上,它类似于使用AJAX的长轮询方法。但是,您确实有内置的安心,浏览器将启动重新连接,而无需编写自定义处理,它仍然使用SSE API结构,使您更容易将服务器端代码移植到类似 Node.js 稍后(如果需要),无需修改前端代码。

请注意,这不会像您在问题中提到的那样缓存连接。尽管允许Apache清理等待"等待的连接,但它应该有助于缓解您的问题。释放这些连接以进行新的呼叫。

答案 1 :(得分:0)

@ War10ck的答案很好。

我还建议reducing KeepAliveTimeout只需几秒钟(如果你需要提供来自同一个虚拟主机的许多其他文件)或disabling KeepAlive altogether(如果它主要用于SSE,你不需要小文件的性能)。这将允许Apache清理"清理"这些联系更快。