消息代理 - .NET Core 中的多供应商体系结构



我目前正在按照.Net Core中的"竞争消费者模式"构建一个系统。因此,我将 JobRequest-Message 放在一个队列中,该队列订阅了多个消费者(工作线程(。其中一个使用者收到消息,执行作业的实际处理。

我还要求构建"独立于供应商"的系统。这意味着我需要以某种方式实现系统,使我可以轻松地在消息代理供应商之间切换,例如:RabbitMq,Azure Service Bus,Amazon SQS(Kafka(。

我们目前正在讨论将其存档的最佳选择,并提出了以下替代方案:

  1. 每个供应商的接口和不同的实现

我为系统所需的各种功能创建接口,并使用供应商的客户端库来实现该接口。缺点当然是,我需要为每个供应商编写一个实现。

  1. 使用 AMQP 1.0 标准客户端库

我坚持AMQP标准并使用AMQP标准库(https://github.com/Azure/amqpnetlite(来实现我的实施。然后,所有基于 AMQP 的消息代理都应只使用一个实现。缺点是,我依赖于AMQP和AMQP版本(RabbitMQ目前使用0.9,Kafka不使用AMQP(。

  1. 在顶部使用已经支持不同代理的服务总线

像NServiceBus或MassTransit(开源(。这将为我的系统增加额外的依赖项并增加其占用空间。NServiceBus也不是免费的,它以某种方式只是将"供应商业务"转移到服务总线上。

首要质量目标是建立一个可靠且有弹性的系统(每天> 100.000 个工作请求(。

请分享您的想法:)

我必须承认我有偏见,因为我是Rebus的作者。不过,这是我的建议:

选择选项 3! 😎

所有提到的服务总线库都是相当非侵入性的,这意味着你最终编写的大部分代码将采用如下所示的形式(示例取自 Rebus,但其他两个提到的库非常相似(:

await bus.Send(command);

用于发送命令,或

await bus.Publish(evt);

用于发布事件,其中bus是一个接口(在本例中IBus(,如下所示:

public class MyCommandHandler : IHandleMessages<MyCommand>
{
public async Task Handle(MyCommand command)
{
// do stuff with the command here
}
}

用于处理消息(无论消息是发送还是发布(。

这意味着您将从库提供的供应商那里获得代码可移植性和独立性的所有好处,而对代码布局的影响非常小。

如果决定实现自己的消息传送代码,则不应花费太多工作将服务总线库的使用替换为自己的传送代码:在这种情况下,创建自己的IBus接口和自己的IHandleMessages<TMessage>接口就足以完全删除依赖项。

只有我的两分钱。 🙂

最新更新