riak_sysmon使用和源码分析
riak_sysmon 是利用 BIF 函数 system_monitor 来监控 Erlang vm 产生的消息状态的项目。下面结合使用来分析一下其源码。
由于使用 system_monitor,那么 riak_sysmmon 仅能做到如下四类事件的捕获:
1. 进程的 heap 超过预设的 heap_word_limit。
2. gc 的收集时间过长超过预设的 gc_ms_limit。
3. 繁忙的文件或者套接口 port。
4. Erlang 节点之间的网络通信烦忙。
riak_sysmon 启动之后,会产生两个 gen 进程。其一为 riak_sysmon_filter,这个进程会做如下工作:
1. 读取app或者config里的阀值(heap_word_limit,gc_ms_limit等)。
2. 根据阀值来启动 system_monitor ,让 vm 发现有超过阀值的状态,发消息给 riak_sysmon_filter 进程。
3. riak_sysmon_filter 对这些消息进行过滤,然后 notify 给另外一个 riak_sysmon_mgr 的 gen_event 进程,通知其做出相应的行为。
开始之时,riak_sysmon_mgr 是没有 handler 来处理对应事件的,需要用户自己写一个 module 来处理消息事件。 我们可以利用项目自带的一个 example 来看看效果,这个 exmaple 仅仅是把收到的事件通过 error_logger 给打印出来,我们来使用 riak_sysmon :
erl -sname node1 -boot start_sasl -pa ebin (node1@hoterran-laptop)1> application:start(riak_sysmon). ok (node1@hoterran-laptop)2> riak_sysmon_example_handler:add_handler(). ok
两个进程已经启动,handler 也设置后,我们来构造一个让 heap 逐渐涨大的例子 t.erl:
-module(t).
-behaviour(gen_server).
-export([start_link/1]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-define(SERVER, ?MODULE).
-record(state, {l}).
start_link(Args) ->
gen_server:start_link({local, ?SERVER}, ?MODULE, [Args], []).
init([Args]) ->
io:format("Args is ~p~n", [Args]),
{ok, #state{l=[]}, 1000}.
handle_call(Msg, {From,_}, State) ->
{reply, call_ok, State}.
handle_cast(Msg, State) ->
{noreply, State}.
handle_info(Info, State) ->
L = State#state.l ++ lists:duplicate(1000, "test"),
{noreply, #state{l=L}, 1000}.
terminate(Reason, _State) ->
ok.
code_change(_OldVsn, _State, _Extra) ->
{ok, _State}.我们启动这个 t 之后,他的 heap 会逐渐变最终超过预设的 heap 阀值,最后触发了 system_monitor 的信息。
(node1@hoterran-laptop)3> t:start_link("test").
Args is "test"
{ok,<0.60.0>}
(node1@hoterran-laptop)4>
=INFO REPORT==== 22-Oct-2012::19:25:43 ===
Example: event {monitor,<0.60.0>,large_heap,
[{old_heap_block_size,0},
{heap_block_size,17711},
{mbuf_size,0},
{stack_size,10},
{old_heap_size,0},
{heap_size,10015}]}
=INFO REPORT==== 22-Oct-2012::19:25:44 ===
Example: event {monitor,<0.60.0>,large_heap,
[{old_heap_block_size,28657},
{heap_block_size,28657},
{mbuf_size,0},
{stack_size,10},
{old_heap_size,6012},
{heap_size,8003}]}
=INFO REPORT==== 22-Oct-2012::19:25:46 ===
Example: event {monitor,<0.60.0>,large_heap,
[{old_heap_block_size,28657},
{heap_block_size,46368},
{mbuf_size,0},
{stack_size,10},
{old_heap_size,6012},
{heap_size,22003}]}总结
riak_system_filter 有如下好处:
1. 对于以上 1,2 类的消息条数进行过滤,每秒仅仅捕获前 proc_limit 条。
2. 对于 3,4 每秒仅仅捕获前 port_limit 条,避免瞬时接受过多的消息。
3. 原来的 system_monitor 只能发送某个进程,这里可以通过 filter 转发 gen_event:notify 给多个 handler 进程来分别处理。
比较简单就说到这里。
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:hoterran 来源: 运维和开发
- 标签: riak_sysmon
- 发布时间:2012-10-26 13:22:55
-
[927] WordPress插件开发 -- 在插件使用 -
[126] 解决 nginx 反向代理网页首尾出现神秘字 -
[51] 如何保证一个程序在单台服务器上只有唯一实例( -
[50] 整理了一份招PHP高级工程师的面试题 -
[48] CloudSMS:免费匿名的云短信 -
[48] Innodb分表太多或者表分区太多,会导致内 -
[48] 用 Jquery 模拟 select -
[48] 全站换域名时利用nginx和javascri -
[48] 海量小文件存储 -
[46] ps 命令常见用法