【发布时间】:2014-10-08 09:03:14
【问题描述】:
Cowboy 是用 erlang 编写的网络服务器。它为每个请求生成新进程,而不是使用该进程处理后续请求,如果 HTTP 流水线(一个接一个地在同一个套接字上发送多个请求,而不等待响应,并假设响应将以与发送请求相同的顺序发送回)被客户端使用。
这很好,但是如果你想使用那个 webserver 来构建实时 web 应用程序,它有一个问题,那就是当 socket 因为客户端网络问题而关闭时,代表服务器上那个 socket 的进程被终止.这意味着您不能使用该进程来存储某些会话数据(因为在实时 Web 应用程序中,您可能希望在 http 请求结束后进行(例如,如果使用长轮询)并且将某些状态与连接的客户端相关联即使http请求已经结束,也可以将他视为“他在线”。
在 sock.js 中,它通过为每个客户端(每个会话 id)生成一个多进程来解决。
因此,如果您有 2000 个使用 websockets 的客户端,您将拥有大约 4k 个进程(一个来自牛仔的进程代表该套接字,另一个用于保持会话状态以防牛仔进程将被终止(例如,由于网络问题)。
问题是:我在 erlang 中相对较新,所以我不知道它在性能改进问题上是否有意义,但我正在考虑稍微重写那个 Cowboy 网络服务器表示实时连接的进程在我想要它之前不会结束(即使底层的 websocket 套接字将被终止,该进程也将处于活动状态)。
这将消除为每个客户端增加一个会话进程的需要。因此,您将只有 2000 个进程,而不是 4000 个进程。它可以成为 erlang 中巨大的性能提升器吗?
【问题讨论】:
-
请记住,Erlang 进程与 OS 进程完全不同。 Erlang 进程并不昂贵,最好将其视为结构化计算的工具。牛仔重写很可能对性能没有帮助。如果您的唯一目标是减少进程数量,甚至可能会受到伤害。
-
你为什么用 Elixir 标记这个问题?
-
@OnorioCatenacci: 好吧,它们都在 erlang vm 上运行,而且这个问题即使对于长生不老药也是有效的,但如果你愿意...
-
你误会我了。我问你为什么用 Elixir 标记这个问题,因为我认为你可能忘记添加一些额外的 Elixir 特定细节。
-
也许您可以尝试将会话数据存储在 ETS 中,看看这是否足以满足您的需求。我觉得这将是一种常见的方法。