4

我正在尝试找出在 erlang 演讲中提到的设计模式。从本质上讲,演讲者提到了使用“消息作为进程”来使用工作队列,而不是将作业用作进程。

关键思想是,通过使用“消息作为进程”,您可以节省序列化/反序列化开销。

谢谢

4

1 回答 1

16

假设M是一个 Erlang term(),它是我们在系统中发送的消息。一种明显的处理方法M是构建流程和队列的管道。M由管道中的第一个工作人员处理,然后发送到下一个队列。然后它被下一个工作进程拾取,再次处理并放入队列中。以此类推,直到消息被完全处理。

可能不太明显的方法是定义一个流程P,然后M交给P. 我们将其记为P(M)。现在消息本身是一个过程,而不是一段数据P将做与工作人员在队列解决方案中所做的相同的工作,但它不必支付将M背部插入队列并再次将其取出等的开销。处理P(M)完成后,该过程将简单地结束其生命。如果交给另一条消息M',我们将简单地生成P(M')并让它同时处理该消息。如果我们得到一组流程,我们就会这样做[P(M) || M <- Set],依此类推。

如果P需要进行同步或消息传递,它可以这样做而不必“模拟”消息,因为它就是消息。与工人队列方法相比,工人必须对随之而来的消息负责。如果P有错误,只有P(M)受错误影响的消息会崩溃。同样,与工作队列方法相比,管道中的崩溃可能会影响其他消息(主要是在管道设计不当的情况下)。

所以总结的诀窍是:将消息转化为成为消息的过程。

成语是“一个进程一个消息”,在 Erlang 中很常见。制作一个新工艺的价格和开销足够低,以至于它可以工作。但是,如果您使用这个想法,您可能需要某种过载保护。原因是您可能希望限制并发请求的数量,以便控制系统的负载,而不是盲目地让它破坏您的服务器。一种这样的实现是由 Erlang Solutions 创建的Jobs,请参阅

https://github.com/esl/jobs

Ulf Wiger 将在以下地点展示它:

http://www.erlang-factory.com/conference/ErlangFactoryLiteLA/speakers/UlfWiger

正如 Ulf 在演讲中暗示的那样,我们通常会在外部进行一些预处理P以解析消息并将其内部化到 Erlang 系统中。但是我们会尽快通过将消息包装在一个进程()中来将它M变成一个作业。P(M)因此,我们立即获得了 Erlang 调度程序的好处。

这种选择还有另一个重要的后果:如果处理一条消息需要很长时间,那么 Erlang 的抢占式调度器将确保处理需求较少的消息仍然得到快速处理。如果您的工作队列数量有限,最终可能会导致其中许多被阻塞,从而影响系统的吞吐量。

于 2011-01-03T16:41:41.833 回答