谁引起busy_dist_port
July 4th, 2013
原创文章,转载请注明: 转载自系统技术非业余研究
本文链接地址: 谁引起busy_dist_port
Erlang节点间RPC通道的载波是tcp,实现上是一个带特殊标志的tcp port, 当这个节点由于某种原因发生拥堵的时候,就会影响到节点间的交互,是个很严重的事情,具体参见 Erlang集群RPC通道拥塞问题及解决方案 博文。
riak_sysmon 提供了busy_dist_port的监控方法,我们在这基础上改进了下,在日常环境中发现了不少busy_dist_port问题,如图:
从图中可以看出,我们的系统在几天前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.

Recent Comments