2

NServiceBus の構成中に次の例外が発生するセルフホット WCF ホスト (IIS) があります。

スローされる例外: NServiceBus.Core.dll の 'Autofac.Core.Registration.ComponentNotRegisteredException'

追加情報: 要求されたサービス 'NServiceBus.Timeout.Core.IPersistTimeouts' は登録されていません。この例外を回避するには、コンポーネントを登録してサービスを提供するか、IsRegistered() を使用してサービス登録を確認するか、ResolveOptional() メソッドを使用してオプションの依存関係を解決します。

インメモリ永続性MSMQ transportを備えた 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を初めて使用し、なぜこれが起こっているのか説明できません. 上記を有効にするメソッドを探していました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:

David の提案を適用し、構成を最小限に抑えた後でも、InMemoryPersistence ではなく MsmqPersistence を使用する場合にのみ例外が発生します。他の永続ストレージは試していません。

この例外は、フル バス (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;
}

繰り返しますが、これは、 Some_Endpoint によって公開されたイベントにサブスクライブするMsmqPersistenceを使用する MVC アプリケーションで発生しています。上記の WCF ホストは、最初にその Some_Endpoint にコマンドを送信します。

4

1 に答える 1

1

ここでいくつかのことが起こっているように見えるので、問題に寄与する可能性のある多くのポイントに対処します.

アセンブリスキャン

このコードは、NServiceBus にとって重要な型をスキャンするアセンブリを制御しています。

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

これにより、重要なアセンブリを誤って除外すると、奇妙なことが起こる可能性があります。を使用AllAssembliesして 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)パージするキューがないため、あまり意味がありません。

さらに、サガとタイムアウト キューについて話していますが、送信専用のエンドポイントはメッセージを処理できません。つまり、サガもありません。これらの組み合わせにより、奇妙なエッジ ケースが発生する可能性があります。

機能の有効化/無効化

特定の機能を無効にする呼び出しがいくつか見られます。

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

config.DisableFeature<StorageDrivenPublishing>();

SecondLevelRetries はタイムアウトを必要とするものの 1 つです。そのため、それを無効にして saga がない場合、InMemory タイムアウト パーシスタが登録されない原因となる固有の設定の組み合わせがどこにあるのかを確認できました。これはバグです。

機能の出力で次のことに注意してください。

  • InMemoryTimeoutPersistence は TimeoutManager により無効になっています
  • それでも、TiemoutManager は有効になっています。これはおそらくバグである可能性があります。

いつでも問題を強制しようとすることができます:

config.EnableFeature<InMemoryTimeoutPersistence>();

ただし、通常は、機能を個別に有効/無効にするのではなく、機能が自分で物事を把握できるようにする方が適切です。

カップル関連のメモ:

  1. メッセージを失わないようにするために SecondLevelRetries を無効にすることは、一種の逆です。インメモリ永続性を使用すると、メッセージが失われます。開発にのみ適しています。本番環境では、他の永続化オプションのいずれかを使用する必要があります。ただし、デバッグ時に例外トレースが繰り返されないようにするために、開発で SLR をスキップすることがいかに価値があるかはわかります。
  2. なぜ StorageDrivenPublishing を無効にするのですか? MSMQ には (RabbitMQ や Azure Service Bus のように) 組み込みの Pub/Sub がないため、この機能がないと、イベントをまったく発行できません。

その他

NServiceBus に渡す前に、Autofac コンテナーがどのように構成されているかに関連している可能性があります。そのコードを見ることができないので、推測するのは難しいです。

あなたが提供したコードで再現を試みましたが、失敗することはありませんでした。上記のいずれも機能せず、単純な再現 (たとえば、必要最小限の Windows コンソール アプリケーション プロジェクト内で作成されたバス) を作成できる場合は、かなり簡単に修正するか、少なくとも作成する必要があります。より良いエラー メッセージが表示されることを確認してください。

編集: MsmqPersistence

MsmqPersistence を使用すると NullReferenceException が発生することは理にかなっています。MsmqPersistence にはサブスクリプション ストレージのみが含まれます。Timeouts、Sagas、Gateway、Outbox など、他の持続性タイプの実装は提供しません。(もしかしたら見逃したかも?)

いずれにせよ、MsmqPersistence は遺物です。使わないで!

開発には、インメモリを使用できます。他の環境では、NHibernate または RavenDB を使用する必要があります。

于 2015-11-12T17:24:37.677 に答える