分布式RabbitMQ节点不能相互识别

时间:2012-06-14 19:35:51

标签: erlang distributed rabbitmq connectivity

我正在开发一个RabbitMQ分布式POC,我坚持集群节点的基础知识。
我正在尝试跟踪兔子的tutorial聚类,所以这是我的参考 在安装了erlang(R14B04)和rabbit(2.8.2-1)后,我将.erlang.cookie文件内容从一个节点复制到另外两个节点。
我不知道如何让erlang注意到这个改变,我不得不重新启动机器(相当蛮力,但我根本不知道erlang)。
另外,我在iptables 4369和另外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_epmd:names()或其他命令中输入以获取更多信息,但我可能在erlang土地上离开了。

真的很感激任何帮助

更新
我尝试手动ping两个erlang节点并返回pang 我做了以下几点:
  连接到两个节点,停止rabbitmq(不确定是否需要但是确定),当erlang命令行启动时启动erlang(erl -sname dilberterl -sname dilbert2)我运行node().在每个人身上分别得到dilbert@HostName1dilbert2@HostName2。然后我尝试使用单引号运行net_adm:ping('dilbert').net_adm:ping('dilbert@HostName1').,并且没有它们来自两个节点(当然更改了名称)并且完成了所有8个案例pang。 当我在其中一台机器上运行nodes().时,我得到了一个空数组 我还尝试允许防火墙中的所有流量(script),然后尝试运行上述命令(不要担心它们现在重新启动)并仍然返回pang。<登记/> 的 UPDATE2:
出于某种原因,我需要解决饼干不匹配问题(感谢@ kjw0188的建议[我在erlang命令行中运行erlang:get_cookie().]。) 这没有帮助,我需要完全停止iptables(不知道为什么,但我很快就会想到)并使用-name dilbert@my-ip加载erlang节点,因为我的机架空间服务器没有dns-name。这最终使我得到了一个乒乓球并看到节点相互看到(nodes().在ping之后返回一个非空数组。) 我现在面临的问题是如何在启动erlang时指示RabbitMQ使用-name而不是-sname。

5 个答案:

答案 0 :(得分:8)

所以我连接两个RabbitMQ节点有多个问题 -
我将添加我的节点托管在rackspace上,因此没有默认的可公开主机名,并且需要iptables,因为没有DMZ或内置安全组概念,如amazon。

<强>问题:
1. Cookie-不确定如何或为什么但我有.erlang.cookie的多个实例(在/root,在我的主目录和/var/lib/rabbitmq/中)我只保留了rabbitmq中的一个并验证了所有实例节点具有相同的cookie 2. IPTables-为了让节点进行通信,我需要打开epmd端口和实际通信的端口范围inet_dist_listen_min inet_dist_listen_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是usuall 4369端口,其他范围使用你想要的任何范围。
${otherNode}是我的其他节点的IP 我还需要通过rabbitmq配置erlang来使用这些端口(参见末尾的配置文件)
3. HostName-看到我没有主机名,我需要编辑兔子脚本以使用-name而不是-sname(第一个告诉erlang采用全名,后者代表简称名称,因此附加@符号和主机名 这是通过编辑完成的:
/usr/lib/rabbitmq/bin/rabbitmqctl
在开头添加了RABBITMQ_NODE_IP_ADDRESS属性的定义

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_NODENAME} \
-name ${RABBITMQ_NODENAME}@${RABBITMQ_NODE_IP_ADDRESS}\
这使得rabbitmq只监听指定的ip地址(在最后的配置文件中指定)并使用该ip而不是usuall主机名加载。

编辑/usr/lib/rabbitmq/bin/rabbitmq-server
将实际的erl命令从-sname ${RABBITMQ_NODENAME} \更改为-name ${RABBITMQ_NODENAME}@${RABBITMQ_NODE_IP_ADDRESS} \

添加了一个兔子conf(/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"

一些帮助我的资源:
RabbitMQ Clustering Guide
Clustering RabbitMQ servers for High Availability
rabbitmq-env.conf(5) manual page
Node communication by public IP address erlang mailing list(中间职位)
Configuring RabbitMQ Cluster on Cloud

希望这会对其他人有所帮助。

修改
不知道我是怎么弄错的,但似乎我的erlang-rabbit端口说明没有被考虑或者还不够。结束了必须允许两个节点之间的所有通信......

答案 1 :(得分:3)

要注意的一件事是erlang cookie文件中的任何类型的空格,尤其是在cookie的内容之后的换行符。只要两者都相同,事情就可以了,但是当一个人有换行而另一个没有换行时,事情就行不通了。

答案 2 :(得分:2)

后台:我在设置Rabbitmq群集时遇到了同样的问题。我在主机上运行了2个docker容器,相当于2个独立的节点,我无法创建这两个节点的集群。

解决方案: 1.确保所有群集节点上都有相同的erlang cookie,默认位置为/var/lib/rabbitmq/.erlang.cookie。此文件用于身份验证,因此请确保在所有节点上都使用相同的文件。更改.erlang.cookie 后重启您的rabbitmq服务。

  1. 确保可以从另一个节点访问节点,使用ping或telnet检查连接。

  2. 检查/ etc / hosts是否有正确的条目,例如,如果rabbit2想要加入集群rabbit1,则应该包含rabbit2的/ etc / hosts。

    172.68.1.6      rabbit1
    172.68.1.7      rabbit2
    
  3. 现在使用$rabbitmqctl stop_app然后$rabbitmqctl join_cluster rabbit@rabbit1停止服务,rabbitmqctl start_app启动您的服务并检查$rabbitmqctl cluster_status以查看您是否已加入群集的天气。

    我按照rabbitmq official documentation设置了群集。

答案 3 :(得分:1)

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

  • 的RabbitMQ的多
  • 的RabbitMQ服务器
  • rabbitmqctl

示例 在脚本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 "$@"

答案 4 :(得分:-2)

<强> http://pearlin.info/?p=1672

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

示例: - rabbit @ node1            兔@节点2

转到rabbit @ node1并从cat /var/lib/rabbitmq/.erlang.cookie复制cookie

转到rabbit @ node2删除当前cookie并粘贴新cookie。

在同一节点上

  

/ usr / sbin / rabbitmqctl stop_app

     

/ usr / sbin / rabbitmqctl reset

     

/ usr / sbin / rabbitmqctl cluster rabbit @ node1

应该这样做。

同样记录在这里。

http://pearlin.info/?p=1672