MassTransit发布到错误端点,如何获取正确的内部总线发布上下文?
解决方案
1. 区分注册双总线实例
MassTransit支持多总线实例隔离,首先需要为内部总线定义专属标记接口,避免和外部总线的默认注入逻辑冲突:
// 定义内部总线专属标记接口 public interface IInternalBus : IBus { } // 服务注册时分开注册两个总线 // 注册外部总线(用于接收外部消息) services.AddMassTransit(x => { x.UsingAzureServiceBus((context, cfg) => { cfg.Host("外部Azure Service Bus连接字符串"); // 配置外部总线的消费者、过滤器等逻辑 cfg.ConfigureEndpoints(context); }); }); // 注册内部总线(用于发布消息到内部) services.AddMassTransit<IInternalBus>(x => { x.UsingAzureServiceBus((context, cfg) => { cfg.Host("内部Azure Service Bus连接字符串"); // 配置内部总线的发布过滤器、端点等逻辑 cfg.ConfigureEndpoints(context); }); });
2. 注入内部总线实例并传递上下文数据
在你的发布类中注入专属的内部总线实例,以及当前外部消费上下文,手动复制需要传递的自定义数据到内部发布上下文:
public class InnerMessagePublisher { private readonly IBus<IInternalBus> _internalBus; private readonly ConsumeContext? _externalConsumeContext; public InnerMessagePublisher(IBus<IInternalBus> internalBus, ConsumeContext? externalConsumeContext = null) { _internalBus = internalBus; _externalConsumeContext = externalConsumeContext; } public async Task PublishAsync(object message, CancellationToken cancellationToken) { await _internalBus.Publish(message, publishContext => { // 复制外部消费过滤器中需要传递的所有数据到内部发布上下文 if (_externalConsumeContext != null) { if (_externalConsumeContext.Headers.TryGetHeader("你的自定义数据键", out var customData)) { publishContext.Headers.Set("你的自定义数据键", customData); } // 按需复制其他上下文属性 publishContext.CancellationToken = cancellationToken; } }, cancellationToken); } }
核心原理说明
- 默认
IPublishEndpoint会自动绑定当前DI作用域内ConsumeContext对应的总线,你处于外部总线的消费作用域时,拿到的必然是外部总线的发布端,因此会把消息发到外部总线。 - 自定义标记接口隔离双总线后,注入
IBus<IInternalBus>可以固定拿到内部总线实例,完全不会和外部总线混淆。 - 全程在外部消费者的原有DI作用域内操作,不需要创建新作用域,手动复制上下文数据后,内部总线的发布过滤器可以正常读取所有传递的自定义属性,满足你的数据传递需求。
内容的提问来源于stack exchange,提问作者Neil
相关产品推荐
相关产品推荐

