如果接收消息的速度很慢,则终止进程

时间:2013-09-19 13:12:23

标签: erlang

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

我是Erlang的新手,我很感激任何指针。如果使用Erlang消息很难实现,也许我可以使用套接字?如果是的话,有例子吗?

编辑:

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

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

注册过程使用监视器监视订阅者。订阅者由Web服务器控制,当连接关闭时,为此连接提供服务的进程将终止。

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

基本上我想在http客户端太慢时关闭连接。

3 个答案:

答案 0 :(得分:3)

在Erlang中传递的消息很棒,但它也可能成为它的弱点之一。如果您发送的消息多于可以处理的消息,则可以快速压制进程。

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

process_info(self(),message_queue_len).

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

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

  1. erlang VM将复制接收者邮箱中的每条消息,而不是二进制引用,因此为了尽可能降低内存,请确保您理解并充分利用binaries
  2. 不要忘记tcp堆栈也是使用进程实现的,因此真正的瓶颈可以在底层库中。
  3. 确保对您的代码进行概要分析(对于Erlang尤其如此),只有概要分析才能告诉您需要进行哪些真正的优化。

答案 1 :(得分:3)

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

即使从ets表中读取数据到每个进程的复制仍然存在,只会复制订阅者正在处理的那条消息。

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

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

答案 2 :(得分:0)

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