1

Cowboy 是用 erlang 编写的网络服务器。它为每个请求生成新进程,而不是使用该进程处理后续请求,如果 HTTP 流水线(一个接一个地在同一个套接字上发送多个请求,而不等待响应,并假设响应将以与发送请求相同的顺序发送回)由客户使用。

这很好,但是如果您想使用该网络服务器来构建实时网络应用程序,它有一个问题,那就是当套接字由于客户端网络问题而关闭时,代表服务器上该套接字的进程将终止。这意味着您不能使用该进程来存储一些会话数据(因为在实时 Web 应用程序中,您可能希望在 http 请求结束后进行(例如,如果使用长轮询)并且有一些与连接的客户端相关联的状态即使http请求已结束,也可以将他视为“他在线”。

在 sock.js 中,它通过为每个客户端(每个会话 id)生成一个多进程来解决。

因此,如果您有 2000 个使用 websockets 的客户端,您将有大约 4k 个进程(一个来自牛仔的进程代表该套接字,另一个用于保持会话状态以防牛仔进程将被终止(例如由于网络问题)。

问题是:我在 erlang 中相对较新,所以我不知道它在性能改进问题上是否有意义,但我正在考虑稍微重写 Cowboy 网络服务器,以便表示实时连接的过程不会结束,直到我想要它(即使底层的 websocket 套接字将被终止,该进程也将处于活动状态)。

这将消除为每个客户端增加一个会话进程的需要。因此,您将只有 2000 个进程,而不是 4000 个进程。它可以成为 erlang 中巨大的性能提升器吗?

4

2 回答 2

1

Erlang 非常擅长处理进程,但是,太多的东西都不好。使用进程作为会话的直接映射不是一个好主意。为什么不按逻辑去做呢?我假设您可以拥有一些内存中的存储空间,例如ETS. 或什至mnesia.

如果Web Sockets用于通信,则每个用户都通过一个这样的进程连接,但是,您只需将某个随机唯一映射Session Key到每个单独的进程,因此映射到每个单独的用户。

-记录(客户端,{web_sock_pid,session_key,用户名})。

如果进程退出,并且客户端有重新连接的方式,一旦它重新将自己标识为同一用户,那么,会话密钥仍然存在,但附加进程的 pid 已更改。不要紧。

如果它不是 web 套接字,它只是HTTP REST/JSON/JSONP/XML services,那么它甚至非常容易。在 RAM 中使用 ETS 表。存储一个新会话,定义该会话的参数存储在 RAM 中,然后对于每个请求,会话密钥可以连同其他参数一起出现。消息传递是通过彗星或客户端的频繁检查。

于 2014-08-15T12:57:09.683 回答
1

如果你问我,听起来你正在做一些过早的优化。

Erlang 进程非常便宜。您真的不必担心产生太多进程。

每个 websocket 使用两个进程编写它,然后进行一些测量以查看它在哪里使用最多的内存并浪费了最多的 cpu 周期。

于 2014-08-21T14:38:23.297 回答