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
- [71] Twitter/微博客的学习摘要
- [65] find命令的一点注意事项
- [64] IOS安全–浅谈关于IOS加固的几种方法
- [63] 如何拿下简短的域名
- [63] android 开发入门
- [62] Go Reflect 性能
- [61] 流程管理与用户研究
- [60] 图书馆的世界纪录
- [60] Oracle MTS模式下 进程地址与会话信
- [58] 读书笔记-壹百度:百度十年千倍的29条法则