使用#amqp_params_direct{}连接RabbitMQ报nodedown错误的问题排查
Erlang程序通过amqp_client连接RabbitMQ节点报{nodedown}错误排查
现象描述
我可以在Erlang Shell中直接连接RabbitMQ节点:
(app@centos7-mq)1> net_kernel:connect_node('rabbit@centos7-mq'). true (app@centos7-mq)2> nodes(). ['rabbit@centos7-mq']
但通过Erlang RabbitMQ Client库编写程序时,出现{error,{nodedown,'rabbit@centos7-mq'}}错误。
相关代码片段
RabbitParams=#amqp_params_direct{username=?RABBIT_USERNAME, password=?RABBIT_PASSWORD, virtual_host=?VHOST, node='rabbit@centos7-mq'}, Connection = amqp_connection:start(RabbitParams), io:format("amqp_connection:start result: ~p~n", [Connection]).
报错信息
amqp_connection:start result: {error,{nodedown,'rabbit@centos7-mq'}}
完整示例代码
-module(amqp_direct). -include_lib("amqp_client/include/amqp_client.hrl"). -compile([export_all]). -compile(nowarn_export_all). -define(RABBIT_USERNAME, <<"your user">>). -define(RABBIT_PASSWORD, <<"your password">>). -define(VHOST, <<"your vhost">>). -define(NODE, 'your server node'). connect_amqp() -> RabbitParams=#amqp_params_direct{username=?RABBIT_USERNAME, password=?RABBIT_PASSWORD, virtual_host=?VHOST, node=?NODE}, io:format("amqp_connection:start begin ~n"), Connection = amqp_connection:start(RabbitParams), io:format("amqp_connection:start result: ~p~n", [Connection]), Connection. start() -> Connection=amqp_example:connect_amqp(), "Finish".
原因分析及解决办法
1. Erlang Cookie不匹配
Erlang分布式节点通信依赖相同的Magic Cookie。Shell中的app@centos7-mq节点能连接RabbitMQ节点,说明两者Cookie一致,但程序启动的Erlang节点可能使用了不同的Cookie:
- 检查程序节点的Cookie:启动程序时,通过
erl -eval 'io:format("~p~n", [erlang:get_cookie()])'查看; - 确保程序节点与RabbitMQ节点Cookie一致:
- 方法一:将RabbitMQ的Cookie(通常在
/var/lib/rabbitmq/.erlang.cookie)复制到程序运行用户的~/.erlang.cookie; - 方法二:启动程序时指定Cookie:
erl -setcookie YOUR_RABBITMQ_COOKIE -s amqp_direct start。
- 方法一:将RabbitMQ的Cookie(通常在
2. 程序启动的节点名称格式问题
amqp_params_direct依赖Erlang分布式连接,要求程序节点与RabbitMQ节点的名称格式一致(短名称-sname或长名称-name):
- 查看RabbitMQ节点名称:执行
rabbitmqctl status,找到node字段; - 启动程序时指定匹配的节点名称:比如RabbitMQ用的是
rabbit@centos7-mq(短名称),则启动程序用erl -sname app@centos7-mq -s amqp_direct start。
3. 代码中的模块调用错误
完整代码中存在明显笔误:模块名为amqp_direct,但start()函数中调用的是amqp_example:connect_amqp(),这会导致函数未定义错误,需修正为amqp_direct:connect_amqp()。
4. 分布式连接前置检查
在调用amqp_connection:start/1前,可先手动建立分布式连接,排查是否是连接问题:
connect_amqp() -> % 先尝试连接节点 case net_kernel:connect_node(?NODE) of true -> io:format("Connected to node ~p~n", [?NODE]); false -> io:format("Failed to connect node ~p~n", [?NODE]) end, RabbitParams=#amqp_params_direct{username=?RABBIT_USERNAME, password=?RABBIT_PASSWORD, virtual_host=?VHOST, node=?NODE}, io:format("amqp_connection:start begin ~n"), Connection = amqp_connection:start(RabbitParams), io:format("amqp_connection:start result: ~p~n", [Connection]), Connection.
内容的提问来源于stack exchange,提问作者孙海城
相关产品推荐
相关产品推荐

