rabbitmq
的代码中包含一个gen_server2
, 其对Erlang OTP中的gen_server进行了一些优化.
gen_server.erl
loop(Parent, Name, State, Mod, hibernate, Debug) ->
proc_lib:hibernate(?MODULE,wake_hib,[Parent, Name, State, Mod, Debug]);
loop(Parent, Name, State, Mod, Time, Debug) ->
Msg = receive
Input ->
Input
after Time ->
timeout
end,
decode_msg(Msg, Parent, Name, State, Mod, Time, Debug, false).
gen_server2.erl
loop(Parent, Name, State, Mod, Time, Queue, Debug) ->
receive
Input -> loop(Parent, Name, State, Mod,
Time, queue:in(Input, Queue), Debug)
after 0 ->
case queue:out(Queue) of
{{value, Msg}, Queue1} ->
process_msg(Parent, Name, State, Mod,
Time, Queue1, Debug, Msg);
{empty, Queue1} ->
receive
Input ->
loop(Parent, Name, State, Mod,
Time, queue:in(Input, Queue1), Debug)
after Time ->
process_msg(Parent, Name, State, Mod,
Time, Queue1, Debug, timeout)
end
end
end.
gen_server2中在主循环中,使用queue保存msg, 需要处理消息时,首先从queue中取出一个消息进行处理,如果queue为空,则使用receive接受消息, 随后处理,如果指定时间内没有任何消息,则处理timeout消息.
将消息保存在queue中, 减小了process内置msg queue的长度, 当我们需要处理消息时,首先从外部的queue中获取消息, 而不用遍历整个内置的msg queue, 当process的负载很大, 也就是消息队列中消息较多时,使用这种方法性能提升很大. 这里其实采用了一个分治的方法,将一个大的消息队列,切分成2个小的消息队列.
gen_server2中有一个不是很完善的地方,就是没有处理 Mod:init/1 返回{ok, State, hibernate}的情况,这个可以参考gen_server结合sys进行实现.
最后看看两者性能比较, 引用Joe' Bog
在merle
所做的测试:
可以看出gen_server2性能有明显提升!
Update:
感谢yufeng的提醒,原谅我的不求甚解.
gen_server2, 其首先从inner msg quue中匹配任意(ANY)一条消息, 随后添加都外部的quue队列中. 随后继续进入Loop循环, 因此, 其实际的做法是首先将所有的消息从inner msg queue中取出,然后放入queue队列, 当inner msg quue没有任何消息时, 也就是after 0 的情况, 然后从queue中取出(queue:out/1)一个消息,交给process_msg进行处理. 如果queue为空,则进行第二次将inner msg导入到quue中的过程.
这样做gen_server2使所有的msg经历了一个从inner msg queue到外部queue的过程, 其减少了虚拟机内部的资源消耗, 但是这些消息都存储到外部的queue, 总体来说内存还是没有什么太大的变化.
最大的不同是:
gen_server2 收到任何一条消息放到外部的queue中, 当inner msg quue为空后,才进行消息处理, 继续循环.
gen_server 收到任何一条消息后,立即进行处理, 处理完成后继续循环.
我没有亲自做测试, 至于上面merle相关的测试, 唯一的解释就是, gen_server2拥有一个比较"空闲"的inner msg queue, 对于其性能提升具有某种好处. 回头我会具体测试一下.
分享到:
相关推荐
otp_win64_25.1.2 rabbitmq-server-3.11.2
OTP是开放电信平台的简称,包含了erlang语言环境。 erlang是函数式语言,提供了9个9的稳定性和超高并发并发性能。 OTP是高并发分布式服务器的最理想平台。
centos otp-OTP-20.0.tar.gz 可兼容rabbitmq3.7.0
rabbitmq-server-3.8.2.exe ErLang_otp_win64_22.2.exe window系统RabbitMQ安装
rabbitmq-server3.7版本和otp_win64安装包,下载解压后,先安装otp_win64.exe 在安装rabbitmq-server ,具体安装步骤可自行百度
rabbitMQ安装包与环境(rabbitmq-server-3.7.0+otp_win64_20.2). 亲测版本兼容,好用 傻瓜式安装
erlang-otp_mibs-19.3.6.4-1.el7.x86_64.rpm
Erlang 安装包(otp_win32_R16B03-1.part2)
资源来自pypi官网。 资源全名:django_otp_yubikey-0.4.0-py2.py3-none-any.whl
是erlang_otp_20.3 的win64安装包,内为exe文件,一路next即可安装完成 是适用于多线程、分布式开发的语言,也是如rabbitmq等重要工具的必须品 使用前需要配置环境变量:1.变量名为ERLANG_HOME,变量值为安装Erlang...
AX3_OTP_Auth-1.0.2-py3-none-any.whl.zip
AX3_OTP_Auth-1.0.4-py3-none-any.whl.zip
AX3_OTP_Auth-1.0.5-py3-none-any.whl.zip
AX3_OTP_Auth-1.0.0-py3-none-any.whl.zip
AX3_OTP_Auth-1.0.1-py3-none-any.whl.zip
AX3_OTP_Auth-1.0.3-py3-none-any.whl.zip