1

我有一个向工作进程发送消息的数据源进程。为了控制内存消耗,我需要终止从邮箱中检索消息缓慢的工作人员。

我是 Erlang 的新手,我将不胜感激。如果用 Erlang 消息很难做到这一点,也许我可以使用套接字?如果有,有例子吗?

编辑:

我有一个从网络读取并生成大量数据的注册进程。它使用 Erlang 消息将这些数据发送到所有“订阅”的进程。对于每个特定的数据,它向所有订阅者发送相同的消息。

我还有一个 Web 服务器,用于流式传输注册进程读取的数据。因此,当 http 客户端连接时,Web 服务器会创建一个进程,该进程订阅已注册的进程并开始接收其消息。

注册的进程使用监视器来监视订阅者。订阅者由 Web 服务器控制,当一个连接关闭时,服务这个连接的进程就会终止。

没有确认,即订阅者在向他们发送消息时不响应。虽然我可以这样对它们进行编程,但我认为它的流量太大了。

基本上,如果 http 客户端太慢,我想关闭连接。

4

3 回答 3

3

在 Erlang 中传递消息很棒,但它也可能成为它的弱点之一。如果您发送的消息超出了进程的处理能力,您可能会很快使进程不堪重负。

一种解决方案是使用以下方法检查控制进程的邮箱大小erlang:process_info/2

process_info(self(),message_queue_len).

这可以帮助您确定您的过程是否太慢,如果您愿意,可以将其终止。

当然这不是唯一的问题,我也不知道你的服务器是如何设计的,所以我只是添加一些可能对你有用也可能没用的建议。

  1. erlang VM 将复制接收者邮箱中的每条消息,只有二进制引用不会,因此为了尽可能降低内存,请确保您理解并善用二进制文件
  2. 不要忘记 tcp 堆栈也是使用进程实现的,因此真正的瓶颈可能在底层库中。
  3. 确保分析您的代码(对于 Erlang 尤其如此),只有分析才能告诉您真正需要优化的地方。
于 2013-09-19T14:20:38.273 回答
3

我建议您使用ets来存储注册进程正在读取的数据,并仅将密钥发送给订阅者进程。现在,所有订阅者都可以随时从 ets 表中读取数据。这样多条消息中的大量数据就不会驻留在进程消息队列中,从而减少了内存消耗。

即使当您从 ets 表中读取数据时,仍然存在将数据复制到每个进程的情况,但只会复制订阅者正在处理的消息。

您可以将消息引用保持在订阅者进程状态,并根据待处理消息的数量来决定订阅者是否运行缓慢(慢速 http 客户端),您可以删除连接。

现在您可以将确认发送回已注册的进程(或任何其他其工作是累积确认并从队列中删除消息的进程),以便它可以从 ets 中删除消息(ets 不是垃圾收集,因此需要删除来自 ets)。

于 2013-09-21T07:08:16.813 回答
0

我最终使用了一个单独的进程来控制目标进程接收到的消息数量。为此,我使用https://github.com/ferd/pobox

于 2013-10-09T21:15:34.203 回答