Erlang:gen_server 还是我自己的自定义服务器?
我需要编写一个服务器,它将接收来自其他模块的指令,并根据收到的指令采取行动。效率是我最关心的问题。那么我是使用 gen_server 还是编写自己的服务器。我所说的“我自己的服务器”的意思是这样的:
-module(myserver).
-export([start/0, loop/0]).
start() ->
spawn(myserver, loop, []).
loop() ->
receive
{From, Msg} -> %Do some action here... ;
message2 -> %Do some action here...;
message3 -> %Do some action here...;
message4 -> %Do some action here...;
.
.
.
_-> ok
end,
loop().
因此,要使用myserver
,我可能会在启动进程时以注册名称注册该进程,然后每个客户端都会使用此 pid 向服务器发送消息。
那么我应该使用这种方法,还是使用 gen_server 行为来实现服务器?使用 gen_server
有什么优势吗?但是与 myserver
相比,使用 gen_server
会增加任何开销吗?
I need to write a server that will receive instructions from other modules and take actions depending on the instructions received. Efficiency is my main concern. So do I use gen_server
or do I write my own server. By "my own server" I mean something like:
-module(myserver).
-export([start/0, loop/0]).
start() ->
spawn(myserver, loop, []).
loop() ->
receive
{From, Msg} -> %Do some action here... ;
message2 -> %Do some action here...;
message3 -> %Do some action here...;
message4 -> %Do some action here...;
.
.
.
_-> ok
end,
loop().
So to use myserver
, I will probably register the process under a registered name while starting it, and then each client will send messages to the server using this pid.
So should I use this method, or instead implement the server using the gen_server
behaviour? Are there any advantages to using gen_server
? But will using gen_server
add any overhead, when compared to myserver
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
与自行实现的服务器相比,gen_server 的开销可以忽略不计,因为它需要对每条消息进行一些额外的函数调用(其中一个是动态的)。我认为您不应该在实施时考虑这一点。您是否在任何时候改变了主意,从
gen_server
迁移到您自己的服务器应该很简单。与简单循环相比,使用
gen_server
可以获得的是:gen_server
will have a negligible overhead compared to self-implemented servers, because it requires a few additional function calls per message (one of which is dynamic). I don't think you should consider this at this point of implementation. Did you changed your mind at any point, moving fromgen_server
to your own server should be straightforward.What you get with
gen_server
compared to a simple loop is:我也会选择
gen_server
。一旦您使用过该设施,您就会学会欣赏它的价值。函数回调可能有点尴尬(例如用于异步调用的handle_cast
),但最终您会习惯它。此外,建议我在没有进行一些测试的情况下不要进行“过早优化”。您可能不想为了边际效率提升而牺牲可读性/可维护性。
I would go with
gen_server
as well. Once you've used this facility, you will learn to appreciate its value. The function callback can be a bit awkward (e.g.handle_cast
for async calls) but in the end, you'll get used to it.Furthermore, I would be advised not to engage in "premature optimization" without having done some testing. You probably don't want to sacrifice readibility/maintainability for marginal efficiency gains.
我会选择
gen_server
只是因为我们花了很多心思让它在各种情况下都能做正确的事情。它负责处理难以正确处理的细节。我想 gen_server 可能会增加一些开销,但我已经停止提供性能建议。如果您真的感兴趣,那么就实现两者并测量速度,这是找出答案的唯一可靠方法。I would go with the
gen_server
simply because so much thought has gone into making it do the right thing under various circumstances. It takes care of details that are difficult to get right. I imaginegen_server
might add some overhead but I've stopped giving performance advice. If you're really interested then implement both and measure the speed, that's the only surefire way to find out.您还可以使用 RabbitMQ 背后的人员提供的 gen_server2 。
它类似于 gen_server,除了以下调整(来自评论):
You can also use gen_server2 by the guys behind RabbitMQ.
It's like gen_server except for the following adjustments (from the comments):
我从你的问题假设你正在编写一个更“永久”的服务器。
一般来说,如果你做得对的话,滚动你自己的服务器会更通用并且更快一点。但是,这是一个大但是:
您必须自己做所有事情,这会增加出错的风险!
如果您希望以 OTP 方式管理您的服务器(如果您正在构建一个强大的系统,您可能会这样做),那么您也必须自己处理所有这些事情。并做到正确。
如果我正在做一个永久服务器,我会开始使用
gen_server
,只有当我在实现我需要的东西时遇到严重困难时才会回退并推出我自己的服务器。寿命短的服务器是另一回事。
I assume from your question that you are writing a more "permanent" server.
In general rolling your own server is more versatile and a little faster, if you get it right. But, and this is a big BUT:
You will have to do everything yourself, which increases the risk of errors!
If you want your server to be managed in the OTP way, which you probably do if you are building a robust system, then you will have to handle all that yourself as well. And get it right.
If I was doing a permanent server I would start out using
gen_server
and only fallback and roll my own if I run into serious difficulties in implementing what I need.Short lived servers are another matter.