我正在开发一个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 dilbert
和erl -sname dilbert2
)我运行node().
在每个人身上分别得到dilbert@HostName1
和dilbert2@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。
答案 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服务。
确保可以从另一个节点访问节点,使用ping或telnet检查连接。
检查/ etc / hosts是否有正确的条目,例如,如果rabbit2想要加入集群rabbit1,则应该包含rabbit2的/ etc / hosts。
172.68.1.6 rabbit1
172.68.1.7 rabbit2
现在使用$rabbitmqctl stop_app
然后$rabbitmqctl join_cluster rabbit@rabbit1
停止服务,rabbitmqctl start_app
启动您的服务并检查$rabbitmqctl cluster_status
以查看您是否已加入群集的天气。
我按照rabbitmq official documentation设置了群集。
答案 3 :(得分:1)
要更改RabbitMQ sname / name行为,您可以编辑脚本:
示例强> 在脚本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
应该这样做。
同样记录在这里。