Home > Erlang探索, 源码分析 > 谁引起busy_dist_port

谁引起busy_dist_port

July 4th, 2013

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

本文链接地址: 谁引起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问题从图中也消失了。

除了监控以外,最核心的问题还是要查出来和那个节点中间的rpc发生问题,什么原因引起的?

以下摘抄的代码可以做这个事情:

get_node_map() ->
    %% We're already peeking inside of the priave #net_address record
    %% in kernel/src/net_address.hrl, but it's exposed via
    %% net_kernel:nodes_info/0.  Alas, net_kernel:nodes_info/0 has
    %% a but in R14B* and R15B, so we can't use ... so we'll cheat.
    %% e.g.
    %% (foo@sbb)11> ets:tab2list(sys_dist).
    %% [{connection,bar@sbb,up,<0.56.0>,undefined,
    %%              {net_address,{{10,1,1,34},57368},"sbb",tcp,inet},
    %%              [],normal}]
    try
        [begin
             %% element(6, T) should be a #net_address record
             %% element(2, #net_address) is an {IpAddr, Port} tuple.
             if element(1, T) == connection,
                size(element(2, element(6, T))) == 2 ->
                     {element(2, element(6, T)), element(2, T)};
                true ->
                     {bummer, bummer}
	     end
         end || T <- ets:tab2list(sys_dist)]
    catch _X:_Y ->
            %%error_logger:error_msg("~s:get_node_map: ~p ~p @ ~p\n",
            %%                       [?MODULE, _X, _Y, erlang:get_stacktrace()]),
            []
    end.

annotate_port(PortType, Port, NodeMap) ->
    try
        %% Need 'try': may race with disconnecting TCP peer
        {ok, Peer} = inet:peername(Port),
	case PortType of
	    busy_port ->
		{busy_port, Peer};
	    busy_dist_port ->
		{busy_dist_port, proplists:get_value(Peer, NodeMap, unknown)}
	end
    catch
        _X:_Y ->
	    Port
    end.

通过调用annotate_port(busy_dist_port, Port, get_node_map()). 我们可以得到引起问题的对端的节点名字。
在我们的个案中是诊断程序的节点引起的,诊断程序一次会拉取大量的用户,数据库等信息进行分析,默认RPC的水位线是1M,很快就满了。我们改成8M问题就差不多解决掉了。

小结:一图胜万言。

祝玩得开心!

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

Comments are closed.