IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

riak_sysmon使用和源码分析

运维和开发 2012-10-26 13:22:55 累计浏览 1,373 次
本机暂存

   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 进程来分别处理。

   比较简单就说到这里。

同分类推荐文章

  1. 从零重建 macOS 开发机:可复现的环境初始化流程 (2026-06-14 20:36:00)
  2. 百度物理网络监控工具开源第二弹:毫秒级监控工具 baize,让你的网络问题无处遁形 (2026-06-11 08:10:28)
  3. How to Set Up Homebrew Tap for Private CLI Tools: A Complete Guide (2026-05-27 02:13:03)

查看更多 DevOps 文章 →

建议继续学习

  1. gen_tcp发送进程被挂起起因分析及对策 (累计阅读 37,821)
  2. gen_tcp发送缓冲区以及水位线问题分析 (累计阅读 6,061)
  3. whatsapp深度使用Erlang有感 (累计阅读 5,828)
  4. Erlang match_spec引擎介绍和应用 (累计阅读 5,634)
  5. 函数式编程很难,这正是你要学习它的原因 (累计阅读 5,419)
  6. php-erlang (累计阅读 5,267)
  7. gen_tcp调用进程收到{empty_out_q, Port}消息奇怪行为分析 (累计阅读 4,248)
  8. ZeroMQ 的模式 (累计阅读 4,059)
  9. Erlang如何限制节点对集群的访问之net_kernel:allow (累计阅读 3,976)
  10. Erlang linkin driver用port_control方式时的一些经验分享 (累计阅读 3,950)