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

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

谢谢

最佳答案

假设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 Scheduler的好处。

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

09-13 13:47