NServiceBus可以在同一个AppDomain中发布给订阅者吗?

时间:2013-09-20 14:11:50

标签: c# nservicebus

我有一个简单的网站。在我的API控制器中,我正在捕获一个命令并将其发送给处理程序。这非常有效。在处理程序中,我做了一些处理,然后发布一个事件。事件永远不会发布。我甚至无法开始描述我为使其工作所做的改变列表,但都无济于事。

关于我唯一可以看到的是我的应用程序和任何样本之间的不同之处在于我的发布者和订阅者在同一个程序集中。在这个时间点,我没有看到需要单独的NServiceBus进程,虽然我可能会在某个时候这样做。

处理程序

public sealed class PortfoliosHandler : IHandleMessages<CreatePortfolioCommand>, IHandleMessages<PortfolioCreatedEvent>
{
    public void Handle(CreatePortfolioCommand message)
    {
        // Processing logic, this executes just fine

        Bus.Publish(new PortfolioCreatedEvent { Name = portfolio.Name });
    }

    public void Handle(PortfolioCreatedEvent message)
    {
        // This NEVER executes
    }
}

配置

<UnicastBusConfig ForwardReceivedMessagesTo="audit">
    <MessageEndpointMappings>
        <add Assembly="Project.Domain" Namespace="Project.Domain.PM.Commands" Endpoint="messagebus" />
        <add Assembly="Project.Domain" Namespace="Project.Domain.PM.Events" Endpoint="messagebus" />
    </MessageEndpointMappings>
</UnicastBusConfig>

配置代码

NServiceBus.Configure.Transactions.Enable();

var config = NServiceBus.Configure.With();

config = config
    .AutofacBuilder(container)
    .Log4Net(new DebugAppender {Threshold = Level.Warn})
    .UseTransport<Msmq>()
    .PurgeOnStartup(true)
    .UnicastBus()
    .LoadMessageHandlers()
    .RunHandlersUnderIncomingPrincipal(false)
    .InMemorySubscriptionStorage()
    .UseInMemoryTimeoutPersister();

var bus = config
    .CreateBus()
    .Start(() => Configure.Instance.ForInstallationOn<NServiceBus.Installation.Environments.Windows>()
                            .Install());

事件处理程序不仅不会触发,而且队列中不会出现任何事件消息,并且日志中不会显示任何已发布的记录。它几乎就像我从未发过它一样。以下是通过调用上面的Publish方法发出的日志条目:

NServiceBus.Unicast.UnicastBus: 15:52:11,984 DEBUG UnicastBus:0 - Invoking transport message mutator: NServiceBus.Transports.Msmq.CorrelationIdMutatorForBackwardsCompatibilityWithV3
NServiceBus.Unicast.UnicastBus: 15:52:11,984 [23] DEBUG NServiceBus.Unicast.UnicastBus [(null)] <(null)> - Invoking transport message mutator: NServiceBus.Transports.Msmq.CorrelationIdMutatorForBackwardsCompatibilityWithV3
NServiceBus.Unicast.UnicastBus: 15:52:12,240 DEBUG UnicastBus:0 - Invoking transport message mutator: NServiceBus.Impersonation.Windows.WindowsIdentityEnricher
NServiceBus.Unicast.UnicastBus: 15:52:12,240 [23] DEBUG NServiceBus.Unicast.UnicastBus [(null)] <(null)> - Invoking transport message mutator: NServiceBus.Impersonation.Windows.WindowsIdentityEnricher
NServiceBus.Unicast.UnicastBus: 15:52:12,488 DEBUG UnicastBus:0 - Invoking transport message mutator: NServiceBus.Unicast.Monitoring.VersionMutator
NServiceBus.Unicast.UnicastBus: 15:52:12,488 [23] DEBUG NServiceBus.Unicast.UnicastBus [(null)] <(null)> - Invoking transport message mutator: NServiceBus.Unicast.Monitoring.VersionMutator
NServiceBus.Unicast.UnicastBus: 15:52:12,743 DEBUG UnicastBus:0 - Invoking transport message mutator: NServiceBus.Unicast.Monitoring.SentTimeMutator
NServiceBus.Unicast.UnicastBus: 15:52:12,743 [23] DEBUG NServiceBus.Unicast.UnicastBus [(null)] <(null)> - Invoking transport message mutator: NServiceBus.Unicast.Monitoring.SentTimeMutator
NServiceBus.Unicast.UnicastBus: 15:52:12,984 DEBUG UnicastBus:0 - Invoking transport message mutator: NServiceBus.Unicast.Monitoring.CausationMutator
NServiceBus.Unicast.UnicastBus: 15:52:12,984 [23] DEBUG NServiceBus.Unicast.UnicastBus [(null)] <(null)> - Invoking transport message mutator: NServiceBus.Unicast.Monitoring.CausationMutator
NServiceBus.Unicast.UnicastBus: 15:52:13,228 DEBUG UnicastBus:0 - Invoking transport message mutator: NServiceBus.Sagas.OriginatingSagaHeaderMutator
NServiceBus.Unicast.UnicastBus: 15:52:13,228 [23] DEBUG NServiceBus.Unicast.UnicastBus [(null)] <(null)> - Invoking transport message mutator: NServiceBus.Sagas.OriginatingSagaHeaderMutator
NServiceBus.Unicast.UnicastBus: 15:52:13,475 DEBUG UnicastBus:0 - Invoking transport message mutator: NServiceBus.Sagas.AutoCorrelateSagaOnReplyMutator
NServiceBus.Unicast.UnicastBus: 15:52:13,475 [23] DEBUG NServiceBus.Unicast.UnicastBus [(null)] <(null)> - Invoking transport message mutator: NServiceBus.Sagas.AutoCorrelateSagaOnReplyMutator
NServiceBus.Unicast.UnicastBus: 15:52:13,721 DEBUG UnicastBus:0 - Invoking transport message mutator: NServiceBus.MessageHeaders.MessageHeaderManager
NServiceBus.Unicast.UnicastBus: 15:52:13,721 [23] DEBUG NServiceBus.Unicast.UnicastBus [(null)] <(null)> - Invoking transport message mutator: NServiceBus.MessageHeaders.MessageHeaderManager
NServiceBus.Unicast.UnicastBus: 15:52:13,969 DEBUG UnicastBus:0 - Invoking transport message mutator: NServiceBus.Gateway.HeaderManagement.GatewayHeaderManager
NServiceBus.Unicast.UnicastBus: 15:52:13,969 [23] DEBUG NServiceBus.Unicast.UnicastBus [(null)] <(null)> - Invoking transport message mutator: NServiceBus.Gateway.HeaderManagement.GatewayHeaderManager

这些是此后不久发生的日志条目:

NServiceBus.Unicast.UnicastBus: 15:52:58,866 DEBUG UnicastBus:0 - Finished handling message.
NServiceBus.Unicast.UnicastBus: 15:52:58,866 [23] DEBUG NServiceBus.Unicast.UnicastBus [(null)] <(null)> - Finished handling message.
NServiceBus.Timeout.Hosting.Windows.TimeoutPersisterReceiver: 15:53:00,900 DEBUG TimeoutPersisterReceiver:0 - Polling for timeouts at 09/20/2013 15:53:00.
NServiceBus.Timeout.Hosting.Windows.TimeoutPersisterReceiver: 15:53:00,900 [17] DEBUG NServiceBus.Timeout.Hosting.Windows.TimeoutPersisterReceiver [(null)] <(null)> - Polling for timeouts at 09/20/2013 15:53:00.
NServiceBus.Timeout.Hosting.Windows.TimeoutPersisterReceiver: 15:53:01,152 DEBUG TimeoutPersisterReceiver:0 - Polling next retrieval is at 09/20/2013 15:54:01.
NServiceBus.Timeout.Hosting.Windows.TimeoutPersisterReceiver: 15:53:01,152 [17] DEBUG NServiceBus.Timeout.Hosting.Windows.TimeoutPersisterReceiver [(null)] <(null)> - Polling next retrieval is at 09/20/2013 15:54:01.

请帮忙。我没办法。我特意将MassTransit移植到NServiceBus,因为命令,事件和消息之间存在分离,但经过4天的攻击,MassTransit看起来非常好。

我确定我做的事情真的很蠢,但我是NServicebus的菜鸟。我甚至买了这本书试图帮助我,但没有用。我看不出自己做错了什么,而且我已经尝试了很多设置的排列,我无法跟踪它们。

更新于2013/09/23

建议我:

  • 将处理程序拆分为两个:PortfolioCreatedHandler和CreatePortfolioHandler。
  • 从处理程序
  • 中删除密封
  • 创建我自己的SubscriptionStorage,包装InMemorySubscriptionStorage以进行调试

我已经使用IEvent来标记我的事件,并使用ICommand来执行我的命令。命令由Web控制器发布,只有处理程序发布事件。

我的TestSubscriptionStorage类正在为Init和GetSubscriberAddressesForMessage调用,不是用于Subscribe和Ubsubscribe,所以看起来问题是事件没有被订阅,这很难与记录下面的条目。

以下是提及PortfolioCreatedEvent的日志:

NServiceBus.Unicast.Routing.StaticMessageRouter: 09:34:25,886 DEBUG StaticMessageRouter:0 - Routing for message: Project.Domain.PM.Events.PortfolioCreatedEvent set to messagebus@SL-T50009909L
NServiceBus.Unicast.Routing.StaticMessageRouter: 09:34:25,886 [1] DEBUG NServiceBus.Unicast.Routing.StaticMessageRouter [(null)] <(null)> - Routing for message: Project.Domain.PM.Events.PortfolioCreatedEvent set to messagebus@SL-T50009909L
MessageType: Project.Domain.PM.Events.PortfolioCreatedEvent, Recoverable: True, TimeToBeReceived: Not set
MessageType: Project.Domain.PM.Events.PortfolioCreatedEvent, Recoverable: True, TimeToBeReceived: Not set
NServiceBus.Unicast.MessageHandlerRegistry: 09:34:25,906 DEBUG MessageHandlerRegistry:0 - Associated 'Project.Domain.PM.Events.PortfolioCreatedEvent' message with 'Project.PM.Handers.PortfolioCreatedHandler' handler
NServiceBus.Unicast.MessageHandlerRegistry: 09:34:25,906 [1] DEBUG NServiceBus.Unicast.MessageHandlerRegistry [(null)] <(null)> - Associated 'Project.Domain.PM.Events.PortfolioCreatedEvent' message with 'Project.PM.Handers.PortfolioCreatedHandler' handler
NServiceBus.Unicast.MessageHandlerRegistry: 09:34:25,916 DEBUG MessageHandlerRegistry:0 - Associated 'Project.Domain.PM.Commands.CreatePortfolioCommand' message with 'Project.PM.Handers.CreatePortfolioHandler' handler
NServiceBus.Unicast.MessageHandlerRegistry: 09:34:25,916 [1] DEBUG NServiceBus.Unicast.MessageHandlerRegistry [(null)] <(null)> - Associated 'Project.Domain.PM.Commands.CreatePortfolioCommand' message with 'Project.PM.Handers.CreatePortfolioHandler' handler
NServiceBus.Serializers.XML.XmlMessageSerializer: 09:34:26,120 DEBUG XmlMessageSerializer:0 - Initializing type: Project.Domain.PM.Events.PortfolioCreatedEvent, Project.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
NServiceBus.Serializers.XML.XmlMessageSerializer: 09:34:26,120 [1] DEBUG NServiceBus.Serializers.XML.XmlMessageSerializer [(null)] <(null)> - Initializing type: Project.Domain.PM.Events.PortfolioCreatedEvent, Project.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
NServiceBus.Unicast.Subscriptions.MessageDrivenSubscriptions.MessageDrivenSubscriptionManager: 09:34:35,445 INFO  MessageDrivenSubscriptionManager:0 - Subscribing to Project.Domain.PM.Events.PortfolioCreatedEvent, Project.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null at publisher queue messagebus@SL-T50009909L
NServiceBus.Unicast.Subscriptions.MessageDrivenSubscriptions.MessageDrivenSubscriptionManager: 09:34:35,445 [18] INFO  NServiceBus.Unicast.Subscriptions.MessageDrivenSubscriptions.MessageDrivenSubscriptionManager [(null)] <(null)> - Subscribing to Project.Domain.PM.Events.PortfolioCreatedEvent, Project.Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null at publisher queue messagebus@SL-T50009909L
NServiceBus.AutomaticSubscriptions.DefaultAutoSubscriptionStrategy: 09:34:35,555 DEBUG DefaultAutoSubscriptionStrategy:0 - Autosubscribed to event Project.Domain.PM.Events.PortfolioCreatedEvent
NServiceBus.AutomaticSubscriptions.DefaultAutoSubscriptionStrategy: 09:34:35,555 [18] DEBUG NServiceBus.AutomaticSubscriptions.DefaultAutoSubscriptionStrategy [(null)] <(null)> - Autosubscribed to event Project.Domain.PM.Events.PortfolioCreatedEvent

1 个答案:

答案 0 :(得分:2)

好的,谢谢你买这本书!是的,您绝对可以订阅来自同一AppDomain的事件。以下是对可能发生的事情的一些想法。

  • 您是否看到表明他们正在订阅该活动的日志条目?如果没有,则他们不订阅。
  • 您没有为您的命令和事件发布代码,因此我不确定您是使用不显眼模式还是直接实现IEvent。 NServiceBus 4不会自动订阅任何未被识别为事件的内容。
  • 我在您的代码中看到InMemorySubscriptionStorage。这使得实际查看该存储有点困难。您可以尝试在某处注入ISubscriptionStorage,以便查看调试器中的内容。或者只是暂时切换到默认的Raven订阅存储,以便您可以在http://localhost:8080导航到RavenDB Studio并查看订阅文档。
  • 我不确定为什么要密封你的处理程序类。我无法想到可能导致的具体问题,但将其作为一个可能的问题将其消除可能是一个好主意。
  • 尝试将处理程序分成不同的类。一个类无论如何都没有理由实现这两个 - 容器会为每条消息启动新实例,因此您无法共享状态,因此最好不要给另一个开发人员留下他们可能的印象。
  • 同样this issue可能与它有关吗?

当然,有时我会成为一个破纪录的记录,但我会caution you not to publish events from a web application in the first place