Home > Erlang探索 > 节点间通讯的通道微调

节点间通讯的通道微调

September 23rd, 2009 Leave a comment Go to comments

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

本文链接地址: 节点间通讯的通道微调

erlang节点间通讯是可以配置的,默认的是inet_tcp 。当2个节点要沟通的时候,net_kernel模块会负责建立必要的连接。 inet_tcp会调用底层的gen_tcp进行数据发送接受。 rpc或者节点间的消息交互都是通过这个port出去的。

在分布节点间,有时候会有大量的消息流动,那么所有的消息都是通过这个port出去 进来,所以这个port的性能极大的影响了节点间通讯的效率。那么有时候, 我们会想微调这个port的参数,根据业务的特点实现效率最大化,但是port如何得到呢?

node_port(Node)->
    {_, Owner}=lists:keyfind(owner, 1, element(2, net_kernel:node_info(Node))),
    hd([P|| P<-erlang:ports(), erlang:port_info(P, connected) == {connected,Owner}])

有了Port, 那么我们就可以设置tcp port的水位线,buffer等等。

inet:setopts(node_port('xx@nd-desktop'), [{high_watermark, 131072}]).

另外要注意 nodeup nodedown可能会换了个tcp链接 要注意重新获取。

还有另外一种方法,设置所有gen_tcp的行为, 比如以下方法:

erl -kernel inet_default_connect_options '[{sndbuf, 1048576}, {high_watermark, 131072}]'

但是这个影响面非常大, 影响到正常tcp的参数了。

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

Categories: Erlang探索 Tags: , ,
  1. piboyeliu
    May 30th, 2013 at 18:34 | #1

    为什么要只用一个连接呢? 不能用多个很麻烦啊。 如果数据量大的化, 还是用 rabbitmq 得了。

    [Reply]

    Yu Feng Reply:

    这个通道是用来传控制信息的,足够的。如果数据量大,还是要自己开tcp通道拉。

    [Reply]

    piboyeliu Reply:

    我的消息通知系统, 推送消息, 如果每个消息只有200字节, 使用 Pid!msg 还是 rabbitmq 更合适?

    [Reply]

    Yu Feng Reply:

    称的上系统的,当然是rabbitmq .

  2. piboyeliu
    May 30th, 2013 at 19:04 | #2

    用udp 是否可以解决?

    [Reply]

  3. piboyeliu
    June 5th, 2013 at 22:52 | #3

    消息推送系统已经初步搭建好了原型, 采用了yufeng 大哥推荐的 rabbitmq.
    但是遇到个问题。
    如果一个queue 有多个consumer 就会有消息乱序的问题, 如果用 consistent-hash-exchange 分散到多个队列,就会遇到如果某个队列的consumer 挂了, 没办法及时处理。queue 的 auto-delete 又会导致消息丢失。
    如果是使用的 Pid! Msg 因为一个tcp 就不会有乱序的问题。
    想了好久都没有一个好的解决方法, 是否应该放弃 解决乱序问题, 而让应用自己考虑呢?

    [Reply]

    piboyeliu Reply:

    或许要考虑修改 consistent-hash-exchange 插件, 发现某个binding 的queue 没有 consumer 就不 转消息到这个队列上。

    [Reply]

    piboyeliu Reply:

    rabbitmq 从 3.0 开始 remove 了 publish 的 immediate 选项, 不知道为什么?

    [Reply]

  4. piboyeliu
    June 6th, 2013 at 00:16 | #4

    考虑自己用nodejs 来监控队列, 如果队列一段时间内没有consumer就 unbinding, 再过段时间就delete queue. 这应该是个折中的方法。队列 设置 Message-TTL 和 dead letter exchange 转消息到一个特殊队列中防止丢消息。 这样系统可以在大多少情形下保证 有序, 异常情况下无序,但尽量不丢消息。

    [Reply]

  5. piboyeliu
    June 18th, 2013 at 01:01 | #5

    “erlang节点间通讯是可以配置的,默认的是inet_tcp”
    怎么调成udp?

    [Reply]

  1. No trackbacks yet.