发布到具有不同存储的多个Rebus队列

本文关键字:Rebus 队列 存储 | 更新日期: 2023-09-27 18:25:32

我们有一个发布消息的应用程序-PublishApp。

消息(MessageA和MessageB)由两个不同的消费者应用程序(ConsumerA和ConsumerB)拾取。

所有应用程序都使用SQL Server作为传输和Windsor配置,但这两个Consumer在SQL Server中有不同的数据库。

我们如何配置PublishApp来为ConsumerA发布MessageA,为ConsumerB发布MessageB

我已经尝试过使用这里描述的DetermineMessageOwnership,但实际上似乎并没有调用它(没有命中断点)。对于返回的字符串端点应该是什么,我有点困惑

我希望我可以在Windsor中设置一个具有特定名称的IBus组件,然后在设置MessageB发布类时按名称引用该组件。然而,目前还不清楚如何在温莎的魔盒之外建立一个IBus,为我做这一切。

如果我尝试调用Configure.With(new WindsorContainerAdapter(container))两次,那么使用Windsor配置会导致Windsor错误,因为它被解释为注册IBus接口两次。我在这里看不到为其中一个IBus实例命名的扩展点,因此无法在Windsor中区分它们。

或者,尝试重用Configure.With...调用会抛出一个错误,告诉我已经在配置程序上调用了.Transport()两次,这也是不允许的(但这会让我使用不同的连接字符串…)

添加XML配置可以让我为不同的消息指定不同的端点,但不能指定不同的SQL连接字符串。

我真正想得到的是这样的东西:

// Set up Bus A
var busA = Configure.With(new WindsorContainerAdapter(container))
    .Transport(tc => tc.UseSqlServerInOneWayClientMode("ConnectionStringA"))
    .Subscriptions(sc => sc.StoreInSqlServer("ConnectionStringA", "RebusSubscriptions"))
    .CreateBus()
    .Start();
// Set up Bus B
var busB = Configure.With(new WindsorContainerAdapter(container))
    .Transport(tc => tc.UseSqlServerInOneWayClientMode("ConnectionStringB"))
    .Subscriptions(sc => sc.StoreInSqlServer("ConnectionStringB", "RebusSubscriptions"))
    .CreateBus()
    .Start();
// Register Bus A in Windsor
container.Register(Component.For<IBus>()
    .Named("BusA")
    .Instance(busA));
// Register a class that depends on IBus, and set it to use Bus A
container.Register(Component.For<IPublishA>()
    .ImplementedBy<PublishA>()
    .DependsOn(Dependency.OnComponent(typeof(IBus), "BusA"));
// And a registration also for IBus B, and for IPublishB to reference named "BusB"

注意:我不想监听多个总线,只想向它们发布事件。其他应用程序正在监视队列,每个应用程序只侦听一个队列上的一个事件。

发布到具有不同存储的多个Rebus队列

我们最终通过删除WindsorContainerAdaptor解决了这个问题。由于我们不处理任何消息,只处理发布/发送,因此我们不需要容器适配器中的任何"handler"内容,并且我们可以将IBus组件的注册切换到配置/启动之外,而不是内部。这使我们可以控制命名IBus注册。

    public static void ConfigureAndStartBus(IWindsorContainer container)
    {
        _RegisterBus(container, "ConnectionStringA" "BusA");
        _RegisterBus(container, "ConnectionStringB" "BusB");
    }
    private static void _RegisterBus(IWindsorContainer container, string connectionString, string busName)
    {
        var bus = Configure.With(new BuiltinContainerAdapter())
            .Transport(tc => tc.UseSqlServerInOneWayClientMode(connectionString))
            .Subscriptions(sc => sc.StoreInSqlServer(connectionString, "RebusSubscriptions"))
            .CreateBus()
            .Start();
        container.Register(
            Component.For<IBus>()
                .Named(busName)
                .LifestyleSingleton()
                .Instance(bus));
    }

然后在类PublishA中,我们可以用对BusA的依赖关系来注册它,并且PublishB可以用对BusB的依赖关系注册。这些消息进入不同的数据库,并由不同的订阅者接收,以便在这些不同的数据库中进行工作。

首先:没有办法(至少目前)在两个SQL Server数据库之间传送消息。为了在端点之间发送/发布消息,您需要在一个共享数据库中使用一个表

您的设置暗示了一些东西在那里,因为您使用"ConnectionStringA""ConnectionStringB"作为传输。

我不清楚你是否真的想/需要做pub/sub消息——当你想让每条消息有多个收件人时,pub/sub是你通常会使用的,这通常是某种事件(即一条名称为过去时的消息,如:"发生了这样和那样的事")。

如果您想要一个特定的邮件收件人,则需要bus.Send该邮件,也就是说,您的端点映射将被命中,以便获得该邮件的目的地。

如果你告诉我更多关于你想要实现的目标,我相信我可以帮助你:)