无法通过RabbitMQ .NET客户端发布消息问题求助
这种情况确实有点棘手——明明能搞定交换机、队列的创建和绑定,偏偏消息发不出去,CLI却一切正常。我帮你梳理几个大概率能解决问题的排查方向:
1. 先揪出隐藏的异常
你当前的代码没有异常捕获逻辑,说不定BasicPublish执行时已经抛出了错误,但你完全没察觉到。比如权限不足、参数不匹配这类问题,都会静默失败吗?不会,只是你没接住而已。先给代码套个try-catch,把异常信息打出来:
try { var factory = new ConnectionFactory() { HostName = "localhost" }; using (var connection = factory.CreateConnection()) { using (var channel = connection.CreateModel()) { channel.ExchangeDeclare(exchange: "e1", type: ExchangeType.Direct, durable: true, autoDelete: false); var declared = channel.QueueDeclare(queue: "qx", durable: true, exclusive: false, autoDelete: false); channel.QueueBind("qx", "e1", "key"); var body = Encoding.UTF8.GetBytes("something"); var props = channel.CreateBasicProperties(); props.Persistent = true; channel.BasicPublish(exchange: "e1", routingKey: "key", props, body: body); } } } catch (Exception ex) { Console.WriteLine($"消息发送失败:{ex.Message}\n{ex.StackTrace}"); }
很多时候,异常信息会直接告诉你问题出在哪——比如队列参数不匹配、RabbitMQ权限不够。
2. 检查队列声明的exclusive参数
你代码里QueueDeclare的第三个参数传了true(也就是exclusive: true),这个参数的意思是只有创建队列的当前连接能访问它,连接关闭后队列会被自动删除。但你说CLI能看到这个队列,这就矛盾了——CLI是另一个独立连接,正常来说看不到exclusive队列的。
要么是你之前用其他方式创建了一个非exclusive的同名队列,要么就是这个参数导致你的.NET程序根本没用到预期的队列。赶紧把exclusive改成false,毕竟你需要CLI和.NET程序都能访问这个队列:
var declared = channel.QueueDeclare(queue: "qx", durable: true, exclusive: false, autoDelete: false);
3. 确保消息真的被RabbitMQ接收了
RabbitMQ客户端的BasicPublish是同步调用,但底层可能会有缓冲。你用using块包裹了通道和连接,可能消息还没来得及发送到服务器,通道就被释放了。试试开启发布确认,强制等待服务器的接收确认:
// 第一步,给连接工厂开启发布确认 var factory = new ConnectionFactory() { HostName = "localhost", PublisherConfirms = true }; // 第二步,在BasicPublish之后等待确认 channel.BasicPublish(exchange: "e1", routingKey: "key", props, body: body); channel.WaitForConfirmsOrDie(TimeSpan.FromSeconds(5));
如果等待超时,说明服务器确实没收到消息,这时候结合异常信息就能定位问题了。
4. 用RabbitMQ管理界面查细节
打开RabbitMQ的Management界面(默认端口15672),看看这些点:
- 交换机
e1和队列qx的绑定关系是否正确,路由键是不是key - 队列
qx的「Messages」统计里,有没有「Ready」或者「Unacknowledged」的消息 - 查看你的.NET程序的连接状态,有没有断开或者异常标记
要是管理界面里队列完全没收到消息,那大概率是路由或者队列参数的问题;要是有消息但没被消费,那就是消费端的问题了(不过你现在是发不出去,先聚焦发布环节)。
内容的提问来源于stack exchange,提问作者Bercovici Adrian

