5

我一直在构建一个实时通知系统。它是 Web 应用程序的一部分,但必须在事件发生时立即查看。长时间轮询不是一种选择,因为当没有可用事件时,Web 服务器保持连接会很昂贵,所以我不得不进行短期轮询。

每个客户端每隔 2 秒访问一次 Web 服务器(这是一个相当高的速率)。当事件可用时,它们将作为 JSON 发送到 JavaScript 客户端。现在,这需要一个服务器设置来处理大量的短期连接。我已经使用 Yaws Web 服务器实现了一个这样的系统。然而,因为 Yaws 启动了许多其他服务,感觉很重,当连接超过 30,000 时,连接开始被拒绝或中止(可能是因为我在 Yaws 运行的同一个 Erlang VM 中运行一些 ETS 表[分离这些可能需要rpc:call/4,我担心这会增加延迟])。我知道有一些特定于操作系统的调整要做,而且已经完成了。

如果集群多个 Yaws 实例很容易,这将不是问题。在 Yaws 中,我使用了一些 appmod,并且我正在以 REST 的方式做事。我在想 Cowboy Web 服务器可能会在这里增强一些东西。我以前没有用过 Cowboy,但我用过 Misultin。看看 Cowboy,它是一个成熟的 OTP 应用程序,它似乎很容易集群,而且是轻量级的,可能会增加整个系统可以处理的客户端数量。存储在 Mnesia 上,我可以轻松地分配它以添加更多节点(可能通过复制),因此每个 Mnesia 实例前面都有一个 Cowboy 实例。

我的问题是:

  1. 我的猜测是否正确,如果我从 Yaws 切换到 Cowboy,我可能会显着提高性能?

  2. Yaws 有一个干净的 API viaAppmods#arg{}记录。Cowboy 是否有这两种东西的等价物(请说明)?

  3. 可以Cowboy处理文件上传吗?如果是这样,您认为在频繁上传文件的情况下使用哪个服务器(Yaws 或 Cowboy)会更好?说明如何使用 Cowboy 完成文件上传。

  4. 可以在同一台机器上运行多个 Yaws 实例。你认为为每台服务器(物理机)创建多个 Yaws 实例并将客户端负载分布在这些实例上会有所帮助吗?我需要知道什么?

  5. 当我设置yaws.conf参数max_connections = nolimit时,如何在 Cowboy 中指定相同的参数?

现在,我关注了Cowboy 作者的采访,他讨论了 Cowboy 比 Yaws 更轻量级的原因。他说

最大的区别是使用二进制文件而不是列表。通用受体池是另一个。我可以列出很多其他的小差异,但我认为这些并不是最有趣的。

那是因为 Cowboy 使用了侦听器池库Ranch,它以某种方式最终具有处理更多连接的更高能力,以及使用二进制文件而不是列表。

同一采访中的另一句话:

由于我们每个连接使用一个进程而不是两个进程,并且我们使用二进制文件而不是列表,因此在没有用户干预的情况下,我们最终使用的内存比其他项目少得多。牛仔也很懒惰,除非需要,它不会做任何事情。所以在用户开始调用函数之前,我们没有太多内存。

我想知道 yaws 是如何处理这种情况的。不知何故,我的问题域需要轻量级的 HTTP 处理。与 Mochiweb、Misultin 或 Cowboy 相比,Yaws 确实会导致更多的内存消耗。我最担心的是,Yaws 拥有最好/最干净的 API,它使我们能够访问#arg{}包含我们需要的所有内容作为 Erlang 记录,这样我们就可以自己将它们取出,而不是其他具有许多用于在外部提取内容的函数的 API。甚至文档:Yaws 文档也非常好且简单明了。也许我需要查看更多的 Cowboy 代码来处理文件上传和简单GET请求POST处理等问题。

否则,我之前提出的问题仍然是紧迫的问题。Yaws 相当不错,但对于这种快速、轻量级、短命、高率的民意调查情况似乎有点过头了,你怎么看?

4

1 回答 1

4

您的 30000 拒绝限制听起来很像某处的 32k 限制。默认进程计数(32k)或文件描述符的某些系统限制等等。您不应该排除限制在内核方面的可能性。由于内核配置非常难以处理,我已经看到系统很容易达到极限。

于 2012-10-18T21:36:08.903 回答