C# Windows服务无法连接RabbitMQ:指定端点均不可达
我用Windows服务(.NET Framework)模板编写了一个C# Windows服务,在Windows 10上连接RabbitMQ时抛出异常:None of the specified endpoints were reachable。
- 连接的是服务所在同一台电脑上的RabbitMQ,在Visual Studio中直接运行代码可正常连接,但安装成服务后,每次执行到
factory.CreateConnection()方法时都会失败。 - 已创建可访问目标虚拟主机的RabbitMQ用户,服务默认以Network Service账户登录,尝试过将服务登录账户改为自定义账户,也将RabbitMQ登录账户从guest替换为自定义账户,问题仍未解决。
- 防火墙未配置阻止连接的规则,当前使用RabbitMQ 3.11.10和Erlang 25.2版本。
每次服务尝试连接时,RabbitMQ日志记录如下:
2023-05-26 14:32:29.934000+01:00 [info] <0.306.1> accepting AMQP connection <0.306.1> ([::1]:63175 -> [::1]:5672)
2023-05-26 14:32:29.944000+01:00 [warning] <0.306.1> closing AMQP connection <0.306.1> ([::1]:63175 -> [::1]:5672):
相关代码片段:
//Set up the RabbitMQ queue factory = new ConnectionFactory { HostName = "localhost", UserName = "username", Password = "password" }; queueName = controller.Settings.QueueName; EventLogger.Log(String.Format("Setting up connection to the RabbitMQ queue {0}", queueName)); connection = factory.CreateConnection(); EventLogger.Log(String.Format("Created the connection")); channel = connection.CreateModel(); EventLogger.Log(String.Format("Created the model")); channel.QueueDeclare(queue: queueName, durable: true, exclusive: false, autoDelete: false, arguments: null);
替换localhost为127.0.0.1
Windows服务的网络上下文对localhost的解析可能存在优先级问题,直接使用IPv4回环地址127.0.0.1替代localhost,避免IPv6解析导致的连接异常。修改代码中的ConnectionFactory配置:factory = new ConnectionFactory { HostName = "127.0.0.1", UserName = "username", Password = "password" };显式指定端口与协议
明确设置AMQP端口5672,并指定使用AMQP 0-9-1协议,避免自动协商出现故障:factory = new ConnectionFactory { HostName = "127.0.0.1", UserName = "username", Password = "password", Port = 5672, Protocol = Protocols.Amqp091 };调整RabbitMQ绑定地址
打开RabbitMQ配置文件(通常为rabbitmq.conf),添加或修改以下配置,确保服务监听所有可用IP(包括IPv4回环地址):listeners.tcp.default = 0.0.0.0:5672修改完成后重启RabbitMQ服务。
验证RabbitMQ用户权限
通过RabbitMQ管理界面(默认端口15672)检查自定义用户对目标虚拟主机的权限,确保已分配配置、写、读权限。添加详细错误日志
在代码中增加连接超时设置和异常捕获,记录更详细的错误信息,便于排查问题:factory.RequestedConnectionTimeout = TimeSpan.FromSeconds(10); try { connection = factory.CreateConnection(); EventLogger.Log("Created the connection"); } catch (Exception ex) { EventLogger.Log($"Connection failed: {ex.Message}\nStackTrace: {ex.StackTrace}"); throw; }
内容的提问来源于stack exchange,提问作者ChrisR

