2

我有一个自加热的 WCF 主机 (IIS),在 NServiceBus 配置期间我得到了这个异常:

抛出异常:NServiceBus.Core.dll 中的“Autofac.Core.Registration.ComponentNotRegisteredException”

附加信息:请求的服务“NServiceBus.Timeout.Core.IPersistTimeouts”尚未注册。为避免此异常,请注册组件以提供服务,使用 IsRegistered() 检查服务注册,或使用 ResolveOptional() 方法解决可选依赖项。

我正在使用具有内存持久性MSMQ 传输的 NSB 5.2.9 。

这是我对自托管 WCF 主机 (IIS) 的配置。没有 App.config!**这在 global.asax 中的 Autofac 注册后调用:

    public static void CreateSelfHost( string endpointName, ILifetimeScope container )
    {
        if ( Bus != null )
            return;

        lock ( syncLock )
        {
            var config = new BusConfiguration();

            config.UseContainer<AutofacBuilder>( c => c.ExistingLifetimeScope( container ) );

            var includesBuilder = AllAssemblies.Matching( "Company.App." );
            config.AssembliesToScan( includesBuilder );

            config.UseSerialization<JsonSerializer>();
            config.UseTransport<MsmqTransport>();
            config.UsePersistence<InMemoryPersistence>();
            config.DisableFeature<SecondLevelRetries>();    //turn off for in-mem persistence, otherwise could lose messages
            config.EndpointName( endpointName );


            config.EnableInstallers(); //ensures msmq is created
            config.PurgeOnStartup( true ); //only for self-hosted

            config.Transactions().Disable();
            config.DisableFeature<StorageDrivenPublishing>();

            Bus = NServiceBus.Bus.CreateSendOnly( config ); //create SendOnlyBus here
        }
    }

所有端点上的配置只能通过IProvideConfiguration<>.

在项目的属性中设置了NServiceBus.Lite配置文件,但这没有区别。

我是 NSB 的新手,我无法解释为什么会发生这种情况。我一直在寻找启用 say 的方法IPersistsTimeouts,但是我找到的任何方法都被标记为过时并且不起作用。

编辑#1: @DavidBoike 要求的功能转储

------------- FEATURES ----------------
Name: CriticalErrorHandling
Version: 5.2.9
Enabled by Default: Yes
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: CustomIDataBus
Version: 5.2.9
Enabled by Default: No
Status: Disabled
Deactivation reason: Did not meet one of the dependencies: [DataBus]
Name: DataBus
Version: 5.2.9
Enabled by Default: Yes
Status: Disabled
Deactivation reason: Did not fulfill its Prerequisites:
   -No databus properties was found in available messages
Name: Encryptor
Version: 5.2.9
Enabled by Default: Yes
Status: Disabled
Deactivation reason: Did not fulfill its Prerequisites:
   -No encryption properties was found in available messages
Name: ErrorSubscribers
Version: 5.2.9
Enabled by Default: Yes
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: ForwarderFaultManager
Version: 5.2.9
Enabled by Default: Yes
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: InMemoryFaultManager
Version: 5.2.9
Enabled by Default: No
Status: Disabled
Deactivation reason: Did not meet one of the dependencies: 
Name: InstallationSupport
Version: 5.2.9
Enabled by Default: Yes
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: CriticalTimeMonitoring
Version: 5.2.9
Enabled by Default: No
Status: Disabled
Deactivation reason: Did not meet one of the dependencies: 
Name: Audit
Version: 5.2.9
Enabled by Default: Yes
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: AutoSubscribe
Version: 5.2.9
Enabled by Default: Yes
Status: Enabled
Dependencies: None
Startup Tasks: ApplySubscriptions
Name: MsmqSubscriptionPersistence
Version: 5.2.9
Enabled by Default: No
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: Scheduler
Version: 5.2.9
Enabled by Default: Yes
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: CustomSerialization
Version: 5.2.9
Enabled by Default: Yes
Status: Disabled
Deactivation reason: Did not fulfill its Prerequisites:
   -CustomSerialization not enable since serialization definition not detected.
Name: ForwardReceivedMessages
Version: 5.2.9
Enabled by Default: Yes
Status: Disabled
Deactivation reason: Did not fulfill its Prerequisites:
   -No forwarding address was defined in the unicastbus config
Name: RegisterHandlersInOrder
Version: 5.2.9
Enabled by Default: Yes
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: SLAMonitoring
Version: 5.2.9
Enabled by Default: No
Status: Disabled
Deactivation reason: Did not meet one of the dependencies: 
Name: LicenseReminder
Version: 5.2.9
Enabled by Default: Yes
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: Outbox
Version: 5.2.9
Enabled by Default: No
Status: Disabled
Deactivation reason: Did not meet one of the dependencies: 
Name: InMemoryGatewayPersistence
Version: 5.2.9
Enabled by Default: No
Status: Disabled
Deactivation reason: Did not meet one of the dependencies: [Gateway]
Name: InMemoryOutboxPersistence
Version: 5.2.9
Enabled by Default: No
Status: Disabled
Deactivation reason: Did not meet one of the dependencies: [Outbox]
Name: InMemorySagaPersistence
Version: 5.2.9
Enabled by Default: No
Status: Disabled
Deactivation reason: Did not meet one of the dependencies: [Sagas]
Name: InMemorySubscriptionPersistence
Version: 5.2.9
Enabled by Default: No
Status: Disabled
Deactivation reason: Did not meet one of the dependencies: [MessageDrivenSubscriptions]
Name: InMemoryTimeoutPersistence
Version: 5.2.9
Enabled by Default: No
Status: Disabled
Deactivation reason: Did not meet one of the dependencies: [TimeoutManager]
Name: TimeoutManagerBasedDeferral
Version: 5.2.9
Enabled by Default: No
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: UnicastBus
Version: 5.2.9
Enabled by Default: Yes
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: BinarySerialization
Version: 5.2.9
Enabled by Default: Yes
Status: Disabled
Deactivation reason: Did not fulfill its Prerequisites:
   -BinarySerialization not enable since serialization definition not detected.
Name: BsonSerialization
Version: 5.2.9
Enabled by Default: Yes
Status: Disabled
Deactivation reason: Did not fulfill its Prerequisites:
   -BsonSerialization not enable since serialization definition not detected.
Name: JsonSerialization
Version: 5.2.9
Enabled by Default: Yes
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: XmlSerialization
Version: 5.2.9
Enabled by Default: Yes
Status: Disabled
Deactivation reason: Did not fulfill its Prerequisites:
   -XmlSerialization not enable since serialization definition not detected.
Name: MsmqTransportConfigurator
Version: 5.2.9
Enabled by Default: No
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: TimeoutManager
Version: 5.2.9
Enabled by Default: No
Status: Enabled
Dependencies: [TimeoutManagerBasedDeferral]
Startup Tasks: None
Name: Sagas
Version: 5.2.9
Enabled by Default: Yes
Status: Disabled
Deactivation reason: Did not fulfill its Prerequisites:
   -No sagas was found in scanned types
Name: SecondLevelRetries
Version: 5.2.9
Enabled by Default: Yes
Status: Enabled
Dependencies: [ForwarderFaultManager]
Startup Tasks: None
Name: DataBusFileBased
Version: 5.2.9
Enabled by Default: No
Status: Disabled
Deactivation reason: Did not meet one of the dependencies: [DataBus]
Name: StorageDrivenPublishing
Version: 5.2.9
Enabled by Default: No
Status: Enabled
Dependencies: None
Startup Tasks: None
Name: MessageDrivenSubscriptions
Version: 5.2.9
Enabled by Default: No
Status: Enabled
Dependencies: None
Startup Tasks: None

编辑#2:

在应用大卫的建议并将配置保持在最低限度之后,我仍然只在使用 MsmqPersistence 而不是 InMemoryPersistence 时遇到异常。我还没有尝试过其他持久性存储。

此异常由具有完整总线(不是 SendOnlyBus)的 MVC 应用程序引发,配置如下:

    public void ConfigureServiceBus( IContainer container, IAppBuilder app )
    {
        var busConfiguration = new BusConfiguration();

        busConfiguration.UseContainer<AutofacBuilder>( c => c.ExistingLifetimeScope( container ) );
        busConfiguration.EnableInstallers();

        var inc = AllAssemblies.Matching( "Company." )
                                            .And( "NServiceBus" )
                                            .And( "ServiceControl" );
        config.AssembliesToScan( inc );

        config.UsePersistence<MsmqPersistence>();
        config.UseSerialization<JsonSerializer>();
        config.UseTransport<MsmqTransport>();

        config.EndpointName( endpointName );

        var startableBus = NServiceBus.Bus.Create( busConfiguration );
        startableBus.Start();
    }

抛出异常:NServiceBus.Core.dll 中的“System.NullReferenceException”附加信息:对象引用未设置为对象的实例。

调用堆栈:

ServiceBus.Core.dll!NServiceBus.Timeout.Hosting.Windows.TimeoutPersisterReceiver.Poll(object obj) 第 90 行 C#

MVC 中的 Autofac 配置:

public static IContainer ConfigureAutofac( IAppBuilder app )
{
    ContainerBuilder builder = new ContainerBuilder();

    // Register your MVC controllers.
    builder.RegisterControllers( typeof( MvcApplication ).Assembly );

    builder.RegisterType<...>().AsImplementedInterfaces();
    //...

    // Set the dependency resolver to be Autofac.
    IContainer container = builder.Build();

    var resolver = new Autofac.Integration.Mvc.AutofacDependencyResolver( container );

    DependencyResolver.SetResolver( resolver );

    return container;
}

同样,这发生在具有MsmqPersistence的 MVC 应用程序中,该应用程序订阅Some_Endpoint 发布的事件。上面提到的 WCF 主机最初将命令发送到该 Some_Endpoint。

4

1 回答 1

1

这里似乎发生了几件事,所以我将讨论一些可能导致问题的要点。

装配扫描

这段代码控制了哪些程序集被扫描以查找对 NServiceBus 重要的类型:

var includesBuilder = AllAssemblies.Matching( "Company.App." );
config.AssembliesToScan( includesBuilder );

如果您碰巧不小心排除了重要的程序集,这可能会导致奇怪的事情发生。UsingAllAssemblies尝试添加 NServiceBus 程序集,但可以肯定的是,您排除了任何 ServiceControl 插件。

如果可能的话,省略此部分并允许端点扫描目录中的所有程序集会更容易。

更好的是:

config.AssembliesToScan(AllAssemblies.Matching("Company.App.")
    .And("NServiceBus")
    .And("ServiceControl"));

或者更好的是,不要列入白名单,但如果绝对必须使用黑名单,因为您有一些疯狂的程序集,其中包含数千种您不想打扰扫描的不相关类型:

config.AssembliesToScan(AllAssemblies.Except("CrazyAssemblies"));

只发送

在您的 WCF 代码片段中,您正在创建一个仅发送总线,但您在它上面有一些奇怪的配置选择:

config.EnableInstallers(); //ensures msmq is created
config.PurgeOnStartup( true ); //only for self-hosted

config.Transactions().Disable();
config.DisableFeature<StorageDrivenPublishing>();

Bus = NServiceBus.Bus.CreateSendOnly( config ); //create SendOnlyBus here

根据定义,仅发送端点不接收消息,因此它不创建队列。EnableInstallers()将不需要,因为不需要设置队列。PurgeOnStartup(true)没有多大意义,因为没有要清除的队列。

此外,您正在谈论 sagas 和超时队列,但仅发送端点无法处理消息,这意味着也没有 sagas。这些事物的组合可能会导致奇怪的边缘情况。

启用/禁用功能

我看到一些调用禁用某些功能:

config.DisableFeature<SecondLevelRetries>();    //turn off for in-mem persistence, otherwise could lose messages

config.DisableFeature<StorageDrivenPublishing>();

SecondLevelRetries 是需要超时的事情之一,所以如果你禁用它并且没有 sagas,我可以看到哪里可能存在独特的设置组合,这会导致 InMemory 超时持久性不被注册,这将是一个错误。

请注意,在您的功能输出中:

  • 由于 TimeoutManager,InMemoryTimeoutPersistence 被禁用
  • 然而,TiemoutManager 已启用。这可能是一个错误。

您总是可以尝试强制解决问题:

config.EnableFeature<InMemoryTimeoutPersistence>();

但通常最好让功能自己解决问题,而不是单独启用/禁用它们。

情侣相关说明:

  1. 为了不丢失消息而禁用 SecondLevelRetries 有点倒退。使用内存中的持久性,您将丢失消息。它只适合开发。对于生产,您应该使用其他持久性选项之一。但是,我可以看到在开发中跳过 SLR 以便在调试时不重复异常跟踪是多么有价值。
  2. 为什么要禁用 StorageDrivenPublishing?MSMQ 没有内置的 Pub/Sub(如 RabbitMQ 或 Azure 服务总线),因此如果没有此功能,您将根本无法发布事件。

各种各样的

它可能与在将 Autofac 容器传递给 NServiceBus 之前如何配置它有关。很难推测,因为我看不到该代码。

我试图用您提供的代码进行复制,但我无法让它失败。如果上述方法都不起作用并且可以进行简单的复制(例如,在基本的 Windows 控制台应用程序项目中创建总线),那么它应该很容易修复,或者至少可以制作确保提供了更好的错误消息。

编辑:MsmqPersistence

使用 MsmqPersistence 时会收到 NullReferenceException 是有道理的。MsmqPersistence 仅包括订阅存储。它不提供其他持久性类型的实现,包括 Timeouts、Sagas、Gateway 和 Outbox。(我可能错过了一个?)

无论如何,MsmqPersistence 是一个遗物。不要使用它!

对于开发,您可以使用内存。对于其他环境,您应该使用 NHibernate 或 RavenDB。

于 2015-11-12T17:24:37.677 回答