跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

C#怎么使用MassTransit消息总线_C# MassTransit RabbitMQ教程【高级】

MassTransit消息失败主因是总线未启动、vhost配置错误或消费者注册时机不当:BusControl需StartAsync()后才能发消息;vhost须严格匹配且URL编码;ReceiveEndpoint必须在启动前注册;消费者需AddConsumer()注册;重试策略须在ReceiveEndpoint内配置。 MassTransit 消息发不出去、消费者不触发、连接看似成功却收不到消息——90% 的问题不是框架 bug,而是总线没启动、vhost 配置错、或消费者注册时机不对。 BusControl 必须 StartAsync() 后才能发布消息 只调用
Bus.Factory.CreateUsingRabbitMq()
或在
AddMassTransit()
里配了 RabbitMQ,但没真正启动总线,
Publish()
就会静默丢弃,不报错、不进队列、日志也几乎没提示。
BusControl
是个状态机,未
StartAsync()
前处于
Created
状态,所有发送操作被直接忽略 .NET 6+ Host 模型中,必须把
IBusControl
注册为
AddHostedService
,否则不会自动调用
StartAsync()
控制台程序要显式 await:
await busControl.StartAsync();
—— 缺这行,消息就发不出去 RabbitMQ vhost 和连接字符串必须严格匹配且 URL 编码 日志显示 “Connected to broker”,但
GetQueues()
查不到消费者队列,或者发消息后队列始终为空,大概率是 vhost 不一致。 RabbitMQ 默认 vhost 是
/
,但云厂商(如腾讯云、阿里云)实例常默认用
/default
或自定义路径(如
/myapp
) 连接字符串里的 vhost 必须 URL 编码:比如
/my/space
要写成
/my%2Fspace
,否则连接会被拒绝或路由失败 用
curl -u user:pass http://localhost:15672/api/vhosts
查实际存在的 vhost 列表,别凭印象写 配置时必须显式指定:
cfg.Host("localhost", 5672, h => { h.VirtualHost("/"); ... })
ReceiveEndpoint 必须在总线启动前注册 如果先
StartAsync()
,再调用
bus.ConnectReceiveEndpoint()
或在总线启动后动态注册
ReceiveEndpoint
,消费者根本不会监听队列,消息进来就堆积或按策略丢弃。 C知道 CSDN推出的一款AI技术问答工具 下载 正确写法:所有
ReceiveEndpoint
必须在
CreateUsingRabbitMq()
的配置委托内声明,或在
AddMassTransit()
回调中通过
ConfigureEndpoints(context)
自动发现 错误写法示例:
var bus = Bus.Factory.CreateUsingRabbitMq(); await bus.StartAsync(); bus.ConnectReceiveEndpoint("my-queue", cfg => { ... });
—— 此时已失效 消费者类必须用
AddConsumer()
注册,且类型需与消息契约完全一致(命名空间、程序集、版本都要对) 重试和超时策略必须在 ReceiveEndpoint 级别配置 全局
UseMessageRetry()
不生效,必须在每个
ReceiveEndpoint
内部配置,否则异常消息不会重试,直接进 error 队列或丢弃。 重试策略不能只写在消费者类里,必须在 endpoint 配置中嵌套:
e.UseMessageRetry(r => r.Intervals(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10)))
超时控制靠
e.PrefetchCount = 1
+
e.TimeToLive = TimeSpan.FromMinutes(5)
,前者防消息堆积阻塞,后者防死信积压 注意
TimeToLive
是消息级 TTL,而
AutoDelete
是队列级行为,两者作用对象不同,别混用 最容易被忽略的是:vhost 的 URL 编码和
StartAsync()
的执行时机。这两个点不卡准,整个消息流就断在第一环,后续所有逻辑都白搭。

相关文章