谁引起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