我正在试图找出erlang谈话中提到的设计模式。 基本上,发言者提到使用“消息作为进程”的工作队列,而不是将作业用作进程。
关键的想法是,通过使用“消息作为进程”,您可以节省序列化/反序列化开销。
由于
答案 0 :(得分:15)
让M
成为Erlang术语(),这是我们在系统中发送的消息。处理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 ,参见
和Ulf Wiger将在以下时间展示:
http://www.erlang-factory.com/conference/ErlangFactoryLiteLA/speakers/UlfWiger
正如Ulf在谈话中暗示的那样,我们通常会在P
之外进行一些预处理来解析消息并将其内化到Erlang系统。但是我们会尽快将消息M
打包到作业中,然后将其包装在一个进程(P(M)
)中。因此,我们立即获得了Erlang Scheduler的好处。
此选择还有另一个重要的分支:如果处理消息需要很长时间,那么Erlang的抢占式调度程序将确保处理需求较少的消息仍然可以快速处理。如果您的工作队列数量有限,最终可能会阻塞其中许多工作队列,从而影响系统的吞吐量。