Erlang 分布式RabbitMQ节点不';我不认识对方

Erlang 分布式RabbitMQ节点不';我不认识对方,erlang,distributed,rabbitmq,connectivity,Erlang,Distributed,Rabbitmq,Connectivity,我正在开发RabbitMQ分布式POC,我被困在对节点进行集群的基础上。 我正试图遵循兔子的聚类规则,所以这是我的参考。 安装erlang(R14B04)和rabbit(2.8.2-1)后,我已将.erlang.cookie文件内容从一个节点复制到另两个节点。 我不确定如何让erlang注意到这一变化,我不得不重新启动机器本身(相当暴力,但我根本不了解erlang)。 此外,我在iptables 4399和5个额外的通信端口中打开,并放置在 /usr/lib64/erlang/bin/sys.c

我正在开发RabbitMQ分布式POC,我被困在对节点进行集群的基础上。
我正试图遵循兔子的聚类规则,所以这是我的参考。
安装erlang(R14B04)和rabbit(2.8.2-1)后,我已将
.erlang.cookie
文件内容从一个节点复制到另两个节点。
我不确定如何让erlang注意到这一变化,我不得不重新启动机器本身(相当暴力,但我根本不了解erlang)。
此外,我在iptables 4399和5个额外的通信端口中打开,并放置在

/usr/lib64/erlang/bin/sys.config
以下配置:

{kernel,[{inet_dist_listen_min, XX00},{inet_dist_listen_max,XX05}]}]
然后,再次重新启动(我知道是哑的)以验证erlang时会考虑这些因素,但在我运行时:

rabbitmqctl cluster rabbit@HostName1
我得到:

Clustering node rabbit@HostName2 with [rabbit@HostName1] ...
Error: {no_running_cluster_nodes,[rabbit@HostName1],
                                 [rabbit@HostName1]}
有可能我摆弄erlang.cookie或端口没有成功,但我不知道如何检查它们。我试着在cmd中键入
erl
,然后键入
erl\u epmd:names()
或其他命令来获取更多信息,但我可能已经远离了erlang

非常感谢您的帮助

更新:
我尝试手动ping两个erlang节点,并返回
pang

我做了以下工作:
连接到两个节点,在erlang命令行启动时停止rabbitmq(不确定是否需要,但要确定),像这样启动erlang(
erl-sname dilbert
erl-sname dilbert2
),我在每个节点上运行
node()dilbert@HostName1
dilbert2@HostName2
。然后我试着运行
net\u adm:ping('dilbert')。
net\u adm:ping('dilbert')dilbert@HostName1“)。
从两个节点(当然更改了名称)分别使用单引号和不使用引号,并在所有8个案例中获得
pang

当我在其中一台机器上运行
nodes()。
时,我得到了一个空数组。
我还尝试允许防火墙中的所有流量(),然后尝试运行上述命令(不用担心,它们现在又打开了),但仍然返回了
pang

更新2:
出于某种原因,我需要解决cookies不匹配的问题(感谢@kjw0188的建议[我在erlang命令行中运行了
erlang:get_cookie()。
)。
这没有帮助,我需要完全停止iptables(不确定为什么,但我很快就会明白),并用
-name加载erlang节点dilbert@my-ip
,因为我的机架空间服务器没有dns名称。这最终使我能够获得一个pong并看到节点之间的相互查看(
nodes()。
在ping之后返回一个非空数组)。

我现在面临的问题是如何指示RabbitMQ在启动erlang时使用-name而不是-sname。

要更改RabbitMQ sname/name行为,可以编辑脚本:

  • rabbitmq多线程
  • rabbitmq服务器
  • 兔mqctl
示例 在脚本rabbitmqctl中,有以下代码段:

exec erl \
    -pa "${RABBITMQ_HOME}/ebin" \
    -noinput \
    -hidden \
    ${RABBITMQ_CTL_ERL_ARGS} \
    -sname rabbitmqctl$$ \
    -s rabbit_control \
    -nodename $RABBITMQ_NODENAME \
    -extra "$@"
您必须在以下位置进行更改:

exec erl \
    -pa "${RABBITMQ_HOME}/ebin" \
    -noinput \
    -hidden \
    ${RABBITMQ_CTL_ERL_ARGS} \
    -name rabbitmqctl$$ \
    -s rabbit_control \
    -nodename $RABBITMQ_NODENAME \
    -extra "$@"

因此,我在连接两个RabbitMQ节点时遇到了多个问题-
我要补充的是,我的节点托管在rackspace上,因此没有默认的可公开主机名,并且需要iptables,因为没有DMZ或内置的安全组概念(如amazon)

问题:
1.Cookie-不知道如何或为什么,但我有多个
.erlang.Cookie
(在
/root
、在我的主目录和
/var/lib/rabbitmq/
)的实例,我只在rabbitmq中保留了一个,并验证了所有节点都具有相同的Cookie。
2.IPTables-为了让节点通信,我需要打开
epmd
端口和实际通信的端口范围
inet\u dist\u listen\u min
inet\u dist\u listen\u max

/sbin/iptables -A INPUT -i eth1 -p tcp --dport ${epmd} -s ${otherNode} -j ACCEPT
/sbin/iptables -A INPUT -i eth1 -p tcp --dport ${inet_dist_listen_min}:${inet_dist_listen_max} -s ${otherNode} -j ACCEPT  
empd
是通常使用的所有4369端口,对于其他范围,请使用您想要的任何范围。
${otherNode}
是我的另一个节点的ip。
我还需要通过rabbitmq配置erlang以使用这些端口(请参见末尾的配置文件)
3.主机名-由于我没有主机名,我需要编辑兔子脚本以使用
-name
,而不是
-sname
(第一个命令erlang使用全名,后者代表短名,因此附加@符号和主机名)。
这是通过编辑完成的:
/usr/lib/rabbitmq/bin/rabbitmqctl

在开头添加了
RABBITMQ_节点_IP_地址
属性的定义

DEFAULT_NODE_IP_ADDRESS=auto
DEFAULT_NODE_PORT=5672
[ "x" = "x$RABBITMQ_NODE_IP_ADDRESS" ] && RABBITMQ_NODE_IP_ADDRESS=${NODE_IP_ADDRESS}
[ "x" = "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_NODE_PORT=${NODE_PORT}

[ "x" = "x$RABBITMQ_NODE_IP_ADDRESS" ] && [ "x" != "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_NODE_IP_ADDRESS=${DEFAULT_NODE_IP_ADDRESS}
[ "x" != "x$RABBITMQ_NODE_IP_ADDRESS" ] && [ "x" = "x$RABBITMQ_NODE_PORT" ] && RABBITMQ_NODE_PORT=${DEFAULT_NODE_PORT}
在实际的erl命令中,我更改了
-sname${RABBITMQ\u NODENAME}\

-name${RABBITMQ\u NODENAME}@${RABBITMQ\u NODE\u IP\u ADDRESS}

这使得rabbitmq只在指定的ip地址(在末尾的配置文件中指定)上侦听,并使用该ip而不是usuall主机名加载

已编辑
/usr/lib/rabbitmq/bin/rabbitmq服务器

将实际erl命令从
-sname${RABBITMQ\u NODENAME}
更改为
-name${RABBITMQ\u NODENAME}@${RABBITMQ\u NODE\u IP\u ADDRESS}
\

添加了一个兔子配置文件(
/etc/rabbitmq/rabbitmq env.conf
),其中包含-

#the ip address which rabbit should use, this is to limit rabbit to only use internal rackspace communication and not publicly accessible ports  
NODE_IP_ADDRESS=myIpAdress  
#had to change the nodename becaue otherwise rabbitmq used rabbit@Hostname and not only rabbit  
NODENAME=myCompany
#This instructed rabbit to instruct erlang which ports it should use for its communications with other nodes  
export SERVER_ERL_ARGS="$SERVER_ERL_ARGS -kernel inet_dist_listen_min somePort -kernel inet_dist_listen_max someOtherBiggerPort"
一些帮助我的资源:



(中间的柱子)

希望这能帮助其他人

编辑:

不确定我是怎么弄错的,但我的erlang rabbit端口指令似乎没有得到考虑或是不够的。最后不得不允许两个节点之间的所有通信…

真正需要注意的是erlang cookie文件中的任何类型的空白,特别是cookie内容之后的换行符。只要两者都相同,事情就没问题,但当一个有断线而另一个没有断线时,事情就不起作用了。

因此,您需要从尝试连接的节点复制cookie

示例:-rabbit@n
172.68.1.6      rabbit1
172.68.1.7      rabbit2