2

我正在用 erlang 编写一个处理大量消息(记录)的服务器。每条消息都有一个标签(原子),如用户 ID。

如果该进程不存在,“路由器”将为该用户生成一个专用的永久进程(在保存和传递消息之前累积几分钟的消息)。否则它将作为消息传递给现有的进程邮箱。

问题是路由表的簿记。

我可以考虑序列化路由器,每条消息都会导致 ETS 查找通过 userId 查找 PID,如果它没有退出,则最终 Spawn 和 ETS 插入。但这在几秒钟内就变得拥挤了。

另一种方法是直接生成一个进程来路由每条消息,但是如果发送给单个用户的几条消息接踵而至,并且在 ETS 中找不到它们对应的 PID 并生成了永久进程,这可能会导致竞争状况。消息将丢失,只有最后生成的进程有效(覆盖 ETS 中的其他进程),而其他进程将处于空闲状态且未被跟踪。

我也可能想错了。有没有更好的方法来处理这种情况?

4

2 回答 2

1

您的第一个解决方案听起来适合这种情况。对我来说,如果您有大量消息,则为收到的每条消息启动一个流程听起来并不正确。ETS 速度很快,应该能够处理大量数据。

您可能要考虑使用 erlang OTP gen_server您可以在此处此处此处阅读有关它的更多信息。

此外,如果您要从多个流程访问 ETS,您可能需要考虑{read_concurrency, true}{read_concurrency, true}选项。在此处此处阅读有关它的更多信息。

于 2016-07-12T08:11:14.077 回答
1

就像您建议的那样,每个用户拥有一个进程(一台服务器)是一种常见的模式。

有时,如果使用的协议允许,不是将消息从侦听所有用户的服务器路由到“用户”进程,而是在任何连接之前产生一个新进程,侦听(等待)新的用户连接请求。当请求到达时,会产生一个新的等待进程,并且当前进程管理与新用户的完整会话(有关详细示例,请参见learyousomeerlang: a bucket of socket)。

于 2016-07-12T09:40:24.913 回答