根据MT文档,每个总线实例应具有不同的队列名称。
WebApi和Backend排队在一起的是什么电线?
考虑更高级的方案
当我设计我的后端管道以使用消息处理时,我可以稍后将其切片并让它在线传输中使用非常简单。问题是,我可以以某种方式配置MT,以便Azure配置的总线将消息中继到配置了本地传输的总线吗?
答案 0 :(得分:2)
我将在MassTransit v3的上下文中回答这个问题,它支持Azure Service Bus和RabbitMQ。如果您打算使用Azure,我强烈推荐使用v3而不是v2的传输。
首先,关于请求。它们应该发送,而不是发布。它们通常是天生的命令,而不是事件。我看到人们发布请求的唯一原因是他们没有服务的端点地址。因此,了解端点有很多帮助。
其次,在您的示例中,每个WebAPI实例都应该拥有自己的队列来接收响应,因为它们会被发送回请求者。使用MT3,每个IBus
实例都有一个唯一的自动删除队列,为此目的设置,以处理来自请求的响应。
GitHub上的MassTransit存储库中有一个示例Sample-RequestResponse,它显示了如何使用RabbitMQ进行设置。它与Azure Service Bus大致相同。
将所有内容组合在一起的“结构”是虚拟主机(在RabbitMQ中)或命名空间(在ASB中)。主题和队列之间的连接决定了它们如何协同工作以形成逻辑总线。
答案 1 :(得分:0)
如果有人尝试使用.NET Core + DI注册多个总线:
TryAddSingleton
呼叫AddBus
仅在尚未为该接口注册实例的情况下才向DI容器添加新实例由于所需的各种接口不是通用的:
TryAddSingleton
Instance
,我们现在注入IBus
IBus<MyRegisteredBus>
属性来访问内置接口实例,并将其存储以供以后使用(在那之后包装器不再起作用)我们希望不必使用带有奇怪的Instance
属性的某种包装器,但是由于内置接口变得通用或使用类似Instance
的东西,我们无法提出一个更优雅的解决方案。
想法/非常欢迎反馈。
通用DynamicProxies
调用(否则与内置调用100%相同的签名):
AddBus
为实现这一目的,我们创建了各种接口/类:
public static void AddBus<TBusType>(this IServiceCollection services, Func<IServiceProvider, IBusControl> busFactory)
where TBusType : class, IBusType
{
IBusControl<TBusType> BusFactory(IServiceProvider serviceProvider)
{
return new BusControl<TBusType>(busFactory(serviceProvider));
}
services.AddSingleton<IBusControl<TBusType>>(BusFactory);
services.AddSingleton<IBus<TBusType>>(provider => new Bus<TBusType>(provider.GetRequiredService<IBusControl<TBusType>>().Instance));
}
如何注册通用 // the only purpose of the interfaces derived from `IBusType` is to uniquely idnetify a registered Bus
public interface IBusType { }
public interface IHosted : IBusType { }
public interface ILocal : IBusType { }
public interface IBusTypeWrapper<TBusType, TInterface>
where TBusType : IBusType
{
public TInterface Instance { get; }
}
public class BusTypeWrapper<TBusType, TInterface> : IBusTypeWrapper<TBusType, TInterface>
where TBusType : IBusType
{
public TInterface Instance { get; }
public BusTypeWrapper(TInterface instance)
{
Instance = instance;
}
}
public interface IBusControl<T> : IBusTypeWrapper<T, IBusControl> where T : IBusType { }
public class BusControl<T> : BusTypeWrapper<T, IBusControl>, IBusControl<T> where T : IBusType
{
public BusControl(IBusControl instance) : base(instance) { }
}
public interface IBus<T> : IBusTypeWrapper<T, IBus> where T : IBusType { }
public class Bus<T> : BusTypeWrapper<T, IBus>, IBus<T> where T : IBusType
{
public Bus(IBus instance) : base(instance) { }
}
public interface ISendEndpointProvider<T> : IBusTypeWrapper<T, ISendEndpointProvider> where T : IBusType { }
public class SendEndpointProvider<T> : BusTypeWrapper<T, ISendEndpointProvider>, ISendEndpointProvider<T> where T : IBusType
{
public SendEndpointProvider(ISendEndpointProvider instance) : base(instance) { }
}
:
ISendEndpointProvider
更新
针对每种总线类型的IHosted服务:
-创建通用的services.AddSingleton<ISendEndpointProvider<ILocal>>(provider => new SendEndpointProvider<ILocal>(provider.GetRequiredService<IBusControl<ILocal>>().Instance));
服务
-在构造函数中注入HostedService<BusType>
-并使用注入的实例开始停止特定总线
然后为每种总线类型注册IBusControl<BusType>
。
IHostedService