erlang - 分布式 RabbitMQ 节点无法相互识别

标签 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 或端口有可能没有成功,但我不知道如何检查它们。我试着打字 erl在 cmd 然后 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 .
更新 2:
出于某种原因,我需要解决 cookie 不匹配问题(感谢 @kjw0188 的建议 [我在 erlang 命令行中运行了 erlang:get_cookie().])。
这没有帮助,我需要完全停止 iptables(不知道为什么,但我很快就会弄清楚)并使用 -name dilbert@my-ip 加载 erlang 节点。因为我的机架空间服务器没有 dns-name。这最终使我能够得到一个 pong 并看到节点彼此看到(nodes(). 在 ping 之后返回一个非空数组)。
我现在面临的问题是如何指示 RabbitMQ 在启动 erlang 时使用 -name 而不是 -sname。

最佳答案

所以我在连接我的两个 RabbitMQ 节点时遇到了多个问题 -
我要补充一点,我的节点托管在机架空间上,因此没有默认的可公开主机名,并且需要 iptables,因为没有 DMZ 或内置安全组概念,如亚马逊。

问题:
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是通常的 4369 端口,对于其他范围,请使用您想要的任何范围。${otherNode}是我另一个节点的ip。
我还需要通过 rabbitmq 配置 erlang 以使用这些端口(请参阅最后的配置文件)
3. 主机名- 因为我没有主机名,所以我需要编辑rabbit 脚本以使用-name而不是 -sname (第一个告诉 erlang 取全名,后者代表短名称,因此附加一个 @ 符号和主机名)。
这是通过编辑完成的:/usr/lib/rabbitmq/bin/rabbitmqctl在开头添加了 RABBITMQ_NODE_IP_ADDRESS 的定义属性(property)
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 而不是通常的主机名。

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

添加了一个 rabbit 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 端口指令没有被考虑或不够。最终不得不允许两个节点之间的所有通信......

关于erlang - 分布式 RabbitMQ 节点无法相互识别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11040141/

相关文章:

erlang - 如何在erlang中禁止ctrl+c

erlang 中的字符串值

java - 模拟网络断开连接以在本地测试分布式应用程序分区

distributed - 顺序和因果一致性

azure - Azure 中的 Rabbit MQ 支持

c# - RabbitMQ 中工作队列的请求-响应模式

java - 是否有任何选项可以使用 Spring-AMQP 在 RabbitMQ 中设置 AutomaticRecoveryEnabled?

scala - 从 rpc 调用到其他节点的错误?

erlang - OTP 行为 : gen_fsm; gen_event. 实际例子?

deep-learning - Pytorch dist.all_gather_object 挂起