Archive

Archive for July, 2013

Erlang新增全面的系统信息收集器-system_information模块

July 29th, 2013 Comments off

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: Erlang新增全面的系统信息收集器-system_information模块

Erlang其实是个操作系统,从下面的图可以看出它的架构:

erlang-vm

erlang系统设计的时候是完全按照unix的理念来平行移植的,它的引导进程叫otp_ring0,第一个进程叫init,有没有感觉很熟悉?
既然是一个操作系统,那么这个系统就是一个非常复杂的系统。erlang vm运行的时候是以unix的进程方式体现的,然后这个进程本身是个小世界,这个世界会跑着很多application,每个application包含配置,数据,模块代码等,多个applcaiton之间相互协作,完成指定的业务目标。

当我们的业务系统出现不按预期执行的时候,那么问题出在哪里呢?我们如何调查呢?
首先erlang当然提供了非常多的调查类的函数,如erlang:system_info,erlang:memory,os:getenv等提供各种各样的信息。但是问题是这些信息是散落在各地的,很难汇集起来提供全面的诊断信息。

官方在最近也认识到了这个问题,在最新的R16版本添加了system_information模块来解决这个问题,具体的patch参考 这里

这个patch总的来讲做了三件比较大的事情:

1. Add system information aggregate
2. Add erts app-file
3. erts: Add cflags, ldflags and config.h into executable

除聚合信息以外,还有一个就是把编译beam的时候的配置, cflags, ldflags 什么的都聚合进去。因为beam vm是依靠操作系统提供各种服务的,如锁,原子,epoll,网络等服务,这些服务每个系统都是不太一样的,出了问题很有必要先调查这些结合处。

新增加的system_information模块位于runtime_tools应用中,它的注释里面也写的清楚:

%% The main purpose of system_information is to aggregate all information
%% deemed useful for investigation, i.e. system_information:report/0.

简单的分析下代码,它聚合的信息主要有以下几块:
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

webtool小问题

July 29th, 2013 Comments off

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: webtool小问题

erlang的观察工具如crashdump,appmon,cover等工具有二种不同的界面:gs(wx)和web。这些tool都遵循一定的接口,用户可以自行扩展这些功能,使的能够融入toolbar或者webtool体系。 其中webtool在线上使用的时候比较方便,因为是web界面,容易过防火墙什么的。

webtool的使用界面如下:
webtool
但是默认的webtool在启动的时候,默认只在127.0.0.1:8888网络上监听,无法在其他机器上查看状态,这样使用起来很不方便。

演示下:

$ erl
Erlang R15B03 (erts-5.9.3.1) [source] [64-bit] [smp:16:16] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.9.3.1  (abort with ^G)
1> webtool:start().
WebTool is available at http://localhost:8888/
Or  http://127.0.0.1:8888/
{ok,<0.35.0>}
2> 

粗粗的研究下webtool的启动代码,可以透过下面的方式来绕开这个问题,注意下面这三个参数都需要的,具体的值用户自己配:

webtool:start(standard_path, [{bind_address, {0,0,0,0}},{port, 8888},{server_name, “foobar”}]).

这种方式默认是全部接口监听:

$ hostname -i
10.232.64.76

看下具体的网卡地址就可以访问到服务了,本例子中是: http://10.232.64.76:8888

祝玩的开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索, 源码分析 Tags:

ms()用途浅析

July 27th, 2013 1 comment

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: ms()用途浅析

erlang系统的application,稍微复杂一点的都会提供一个ms/0的导出函数,而且这个导出函数通常在文档里面找不到描述,很奇怪不是吗?
比如mnesia就有这样的ms, 我们来看下:

$ erl
Erlang R17A (erts-5.11) [source-b7fbc28] [64-bit] [smp:16:16] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V5.11  (abort with ^G)
1> mnesia:ms().
[mnesia,mnesia_backup,mnesia_bup,mnesia_checkpoint,
 mnesia_checkpoint_sup,mnesia_controller,mnesia_dumper,
 mnesia_loader,mnesia_frag,mnesia_frag_hash,
 mnesia_frag_old_hash,mnesia_index,mnesia_kernel_sup,
 mnesia_late_loader,mnesia_lib,mnesia_log,mnesia_registry,
 mnesia_schema,mnesia_snmp_hook,mnesia_snmp_sup,
 mnesia_subscr,mnesia_sup,mnesia_text,mnesia_tm,
 mnesia_recover,mnesia_locker,mnesia_monitor,mnesia_event]
2> 

看起来貌似只是返回组成mnesia的模块列表而已。
那么它的作用是什么呢?

复杂一点的程序都需要在运行期间来进行观察或者优化,比如说dbg跟踪一个函数或者模块运作的时候,是需要这个模块的名字的,如:

dbg:tp(Module,MatchSpec)

那么如果要跟踪整个application的运作,我们通常会写这样的代码:
[do_some_thing(M) || M<-myapp:ms()]. 所以这就是ms的意义所在。 现在的问题是mnesia的代码是把ms的模块硬编码的,这样会带来一个维护的问题,比如添加,改名或者减少一个模块都要记得去修改这个列表,很麻烦。 [erlang] %mnesia.erl ms() -> [ mnesia, mnesia_backup, mnesia_bup, ... ]. [/erlang] 程序员是个很懒的群体,必定不会这么挫的,于是rebar就专门花了点力气把这个事情做的漂亮。 rebar在编译application的时候,会把src/myapp.app.src的内容添加以下内容:

{modules,[mod_a, mod_b,…]}

形成ebin//myapp.app文件,这个文件是每个app必须的!

rebar处理这个事情的核心代码如下:

%%rebar_otp_app.erl
AppVars = load_app_vars(Config1) ++ [{modules, ebin_modules()}],
ebin_modules() ->
    lists:sort([rebar_utils:beam_to_mod("ebin", N) ||
                   N <- rebar_utils:beams("ebin")]).

Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索, 源码分析 Tags: ,

进程死亡原因调查:被杀?

July 25th, 2013 3 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 进程死亡原因调查:被杀?

最近MySQL平台化系统都是用热升级来更新的,在线上的日志发现类似的crashlog:

2013-07-24 23:54:06 =ERROR REPORT====
** Generic server <0.31760.980> terminating
** Last message in was {‘EXIT’,<0.29814.980>,killed}
** When Server state == {state,”app873″,false,172683,33,<<"app873">>,<0.29814.980>,ump_proxy_session,1,[59,32,204,78,86,208,242,122,240,207,269,79,80],[],2,true,<<>>,0,0,{conn_info,{10,246,161,112},10145,”app873″,”8813684fc05fb6cd”},<0.31762.980>,1,{conn_info,{172,18,134,8},10085,”app873″,”8813684fc05fb6cd”},ump_proxy_cherly_server,<0.31763.980>,1,undefined,<<>>,false,true,[],{dict,2,16,16,8,80,48,{[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[]},{{[],[[{session,names},103,98,107]],[],[],[],[],[],[],[[{session,”character_set_results”},78,85,76,76]],[],[],[],[],[],[],[]}}},1,0,0,0,0,0,200,1374681206757732}
** Reason for termination ==
** killed

其中Reason是killed, 有点困扰。

我们知道在热升级的时候会purge用旧代码的进程, purge的时候发现有必要就会exit(P, kill)让进程死亡,但是怎么kill变成了killed呢?

我们看下release_handler和code的代码,验证我们的判断:

%%release_handler_1.erl
eval({purge, Modules}, EvalState) ->
    % Now, if there are any processes still executing old code, OR
    % if some new processes started after suspend but before load,
    % these are killed.
    lists:foreach(fun(Mod) -> code:purge(Mod) end, Modules),
    EvalState;

%%code_server.erl
do_purge([P|Ps], Mod, Purged) ->
    case erlang:check_process_code(P, Mod) of
        true ->
            Ref = erlang:monitor(process, P),
            exit(P, kill),
            receive
                {'DOWN',Ref,process,_Pid,_} -> ok
            end,
            do_purge(Ps, Mod, true);
        false ->
            do_purge(Ps, Mod, Purged)
    end;

release_handler最终确实是调用了exit(P, kill)杀人,可是为什么对端收到killed死因呢?

再深入调查下原因,我们知道exit是虚拟机内部的实现,简单的grep下killed就可以看到send_exit_signal这个执行函数:
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: Erlang探索, 源码分析 Tags:

epmd端口定制

July 6th, 2013 1 comment

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: epmd端口定制

在前面一篇 Erlang epmd的角色以及使用 我们知道epmd是起到节点名称和地址的转换服务,绑定在周知端口4369.
但是这也会带来三个问题:
1. 因为是周知端口,所以通过查询目标机器上的4369,就可以知道这个机器上节点的情况。
2. 在同一机器可能会部署不同的Erlang集群,希望不要互相干扰。
3. 防火墙不允许过4369端口,或者不在开放端口之列表。

这就需要对epmd绑定的端口能够定制。

参见epmd的文档

ERL_EPMD_PORT
This environment variable can contain the port number epmd will use. The default port will work fine in most cases. A different port can be specified to allow several instances of epmd, representing independent clusters of nodes, to co-exist on the same host. All nodes in a cluster must use the same epmd port number.

Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

谁引起busy_dist_port

July 4th, 2013 Comments off

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 谁引起busy_dist_port

Erlang节点间RPC通道的载波是tcp,实现上是一个带特殊标志的tcp port, 当这个节点由于某种原因发生拥堵的时候,就会影响到节点间的交互,是个很严重的事情,具体参见 Erlang集群RPC通道拥塞问题及解决方案 博文。

riak_sysmon 提供了busy_dist_port的监控方法,我们在这基础上改进了下,在日常环境中发现了不少busy_dist_port问题,如图:

sysmon_distbusyport

从图中可以看出,我们的系统在几天前busy_dist_port还是比较严重的,后面我们透过+zdbbl 8192参数来修正了这个问题,busy_dist_port问题从图中也消失了。
Read more…

Post Footer automatically generated by wp-posturl plugin for wordpress.

持续学习的习惯

July 4th, 2013 5 comments

原创文章,转载请注明: 转载自系统技术非业余研究

本文链接地址: 持续学习的习惯

元朔同学的百阿毕业感言写的洋洋洒洒,谁再说程序员没有文学青年,我和谁急! 摘抄部分如下:

霸曰:“学不在多,在乎深也;书不在众,在乎智也。君子生非异也,为何有智与愚之异?人之学无难易,学之,则难者亦易已;不学,则易者亦难矣,是故聪与敏,可恃而不可恃也;自持其聪与敏而不学者,自败者也。孰知卖油翁否?油自钱孔入而钱不湿,盖因熟能生巧也,吾于闲暇时学Erlang,六载积有一万时也,故业精于勤荒于嬉,此万古真理也。”

点点滴滴,持续积累,我相信一万小时投入会让一个人成为领域专家的。
祝学的开心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

Categories: 杂七杂八 Tags: