使用Erlang / OTP的面向服务的体系结构:如何正确使用消息传递

时间:2012-08-03 04:46:47

标签: database activerecord erlang soa otp

我的previous question关于数据库访问和服务抽象的答案帮助我理解,在SOA中,数据库服务应该提供公共API,而不是对数据库的直接访问(SQL或通过ORM)。

现在,如果我想在Erlang / OTP应用程序中创建(SOA)服务,我认为它应该是gen_server或其他OTP行为,因为在这种情况下,API将很容易定义,服务本身可以是很容易纳入应用程序。

但是我应该如何将数据从服务传递给消费者呢?

我知道在Ruby on Rails中我可以做类似

的事情
persons = Person.find(all)

然后我可以将persons返回给服务使用者。

在Erlang / OTP中如果persons是几千条记录,我应该在gen_server return语句中传递它吗?这意味着gen_server将向其调用者(服务使用者)发送消息,该消息将基本上复制到Erlang VM中。我倾向于认为它不适合使用Erlang消息传递。

所以我的问题是:

  • 如何在Erlang / OTP中创建数据库服务(SOA)?
  • 此类服务的API是否应使用OTP标准机制(如gen_server返回消息)或其他任何内容?

1 个答案:

答案 0 :(得分:4)

并非所有Erlang应用程序都需要进行消息传递!此外,并非所有Erlang应用程序都需要使用gen_servers。对于涉及连接的应用程序,例如一个Web应用程序,让我们真正地分析你需要gen_server的位置。

Web服务器(Yaws)将主要生成一个进程来处理每个传入的请求。现在,在您的应用程序中,可能会发生以下情况:

1. You may also be spawning another process to work on the request and then send 
the answer as a message to the first process
2. You could just be processing the request through a bunch of sequential code
in different modules, say direct to mnesia or through an odbc connection e.t.c.
现在,在1的情况下,您已经增加了每个请求的进程数。大多数应用程序与案例2足够平行。 gen_server如何进入这一切?

gen_server是许多事物的抽象。但是,gen_server仍处理请求one-by-one,同时也会创建一个失败点。当然,当它失败时,会有一个restart strategy来提升它。因此,如果您gen_server之间的yaws代表mnesiaan odbc connection to MySQL / Oracle / e.t.c.,那么yaws完成的并行操作就是浪费时间,因为gen_server按顺序为这些进程提供服务。但是,现在,如果每个进程都经过一系列顺序代码来获得答案,那么好处是巨大的。

实际上,我之前创建了一些SOA个应用程序,但它们是RESTFUL性质。我发现实际上,使用say yaws appmods(它们本质上是RESTFUL),如果在数据库中的信息路径中有gen_server,则会很浪费。删除gen_server在应用程序的速度和稳定性方面的性能提升。有时候,mailbox / message box的{​​{1}}会变得太大而且会降低整个系统的速度,因为进程会等待答案。另一件事,因为消息被复制到erlang VM中的所有地方,内存就成了问题。作为确切问题的参考示例,请打开此book (Franceso and Simpsons Erlang Book)并查看页面gen_server,在标题110下,它们会向您显示流程设计模式,错误方式和好方法。