服务器发送事件(Server-Sent Events),Puma,Rails和每个客户端的最大专用线程数

11

我在我的Rails项目中使用Redis来订阅频道,当事件发生时向这些频道发布消息。在客户端,我注册的EventSource与这些频道相对应。每当服务器为已订阅的频道发生事件时,服务器会进行SSE写操作,以使所有注册的客户端都能接收到更新。

现在,连接将一直保持活动状态,直到断开与此类通道相关联的客户端为止,也就是说,专用于此类客户端的服务器线程将继续运行。采用这种方法,如果有1000个并发用户订阅了一个频道,那么我将有1000个TCP/IP连接处于打开状态。

此教程所建议的,我使用Puma作为Web服务器。默认情况下,Puma指定最大线程数为16。我可以将此限制更改为更高的值。

我可能不知道我的应用程序中可能同时存在多少并发用户,并且不知道我可以在Puma中指定的最大线程数。在最坏的情况下,如果专用于每个并发用户的线程计数达到了Puma Web服务器指定的最大线程计数,则应用程序将对所有用户冻结,直到其中一个并发用户断开连接。

我很高兴在我的Rails项目中使用实时流传输和服务器发送事件,但采用这种方法,我有可能会达到Web服务器指定的最大线程计数限制,从而导致应用程序对所有用户不响应,直到其中一个并发用户断开连接。

不确定针对大量并发用户的Puma的典型最大线程计数是多少。

我应该考虑其他方法-也许是基于AJAX的轮询或使用基于事件驱动的非阻塞I/O模型的Node.js?还是只是运行一些基准测试以了解我可以指定的最大线程计数?

1个回答

2
我实际上正在处理一个项目,在这个项目中,由于开放连接问题,我们选择了轮询。我们认为每三秒钟轮询一次会更容易,而不是保持连接打开和挂起。但数据新鲜度要求并不是很严格,只有三秒钟,所以这是可行的,浪费一个线程三秒钟有点傻。
因此,除非您对数据新鲜度有非常严格的要求,和/或有受限制的用户群体,和/或能够拥有大量线程,通常正常轮询是正确的方法。
另一方面,如果他们将不断地访问您的服务器,并且重新轮询数据需要比您的数据新鲜度要求更长的时间,那么最好保持连接打开,以避免再次处理整个堆栈。
此外,在puma 2中,您还可以在集群模式下运行它,这意味着它会生成具有自己线程的额外工作进程,您最终可以得到工作进程x线程=总线程数。这可能有助于您的计算。

https://github.com/puma/puma#clustered-mode


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接