我的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消息传递。
所以我的问题是:
答案 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
代表mnesia
或an 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
下,它们会向您显示流程设计模式,错误方式和好方法。