7

私はNServiceBusを初めて使用し、パブリッシャーと個別のサブスクライバー(v3.2.0.0を使用)を開発しようとしています。これまでのところ、正常に機能しています。パブリッシャーとサブスクライバーの両方がNServiceBusホストで実行されています。私のメッセージはすべて正常に公開されますが、断続的にサブスクライバーによってピックアップされず、パブリッシャーによって次のエラーが表示されます。

2012-09-05 14:27:37,491 [Worker.6] WARN  NServiceBus.Unicast.UnicastBus [(null)]  <(null)> - No handlers could be found for message type: MyNamespace.MyMessage

ただし、この警告はすべてのメッセージに表示されるわけではないため、メッセージの後にメッセージを公開し続けると、すべてがMSMQキューに表示されていても、メッセージの半分がメッセージを表示しているため、サブスクライバーによって取得されない場合があります。

私はこれを理解するのに苦労していることを認めます、それでこれまでの私のコードのいくつかは完全なゴミかもしれません!

私は次のようにNSBにメッセージを公開しています。メッセージ入力は、私が定義したいくつかの異なるタイプの1つです。

private void Publish<T>(T message)
{
    var myBus = Configure.Instance.Builder.Build<IBus>();
    myBus.Publish(message);
}

パブリッシャーのEndpointConfigは次のとおりです。

[EndpointName("MyQueue")]
public class EndpointConfig : IConfigureThisEndpoint, AsA_Publisher, IWantCustomInitialization
{
    /// <summary>
    /// Initialisation for NServiceBus.
    /// </summary>
    public void Init()
    {
        Configure.With()
            .DefaultBuilder()
            .MsmqSubscriptionStorage()
            .DisableTimeoutManager()
            .DefiningEventsAs(t => t.Namespace != null && t.Namespace.StartsWith("MyNamespace"));
    }
}

サブスクライバー側には、次のEndpointConfigがあります。

[EndpointName("MyQueue")]
public class EndPointConfig : IConfigureThisEndpoint, AsA_Server, IWantCustomInitialization
{
    public void Init()
    {
        Configure.With()
            .DefiningEventsAs(t => t.Namespace != null && t.Namespace.StartsWith("MyNamespace"));
    }
}

次のようにEventMessageHandlerを使用します。

public class EventMessageHandler : IEvent, IHandleMessages<IMyMessage>
{
    public void Handle(IMyMessage message)
    {
        Console.WriteLine(string.Format("Subscriber 1 received EventMessage with Id {0}.", message.Id));
    }
}

サブスクライバーのapp.configは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="UnicastBusConfig" type="NServiceBus.Config.UnicastBusConfig, NServiceBus.Core" />
    <section name="MessageForwardingInCaseOfFaultConfig" type="NServiceBus.Config.MessageForwardingInCaseOfFaultConfig, NServiceBus.Core" />
  </configSections>

  <MessageForwardingInCaseOfFaultConfig ErrorQueue="error"/>

  <UnicastBusConfig>
    <MessageEndpointMappings>
      <add Messages="MyNamespace" Endpoint="MyQueue" />
    </MessageEndpointMappings>
  </UnicastBusConfig>
</configuration>
4

1 に答える 1

12

パブリッシャーとサブスクライバーの両方に同じエンドポイント名を使用しているようです。NServiceBus はエンドポイント名を使用してキュー名を生成するため、両方のプロセスが同じキューを使用することになります。

したがって、事実上、パブリッシャーはメッセージをパブリッシュしますが、パブリッシャーとサブスクライバーは、誰がメッセージを処理するかについて争っています。

サブスクライバーが勝つと、意図した動作が表示されます。

パブリッシャーが勝った場合、そのメッセージのハンドラーがないため、NServiceBus は警告を表示します。これは必ずしも問題ではありません。メッセージを受信して​​単純に無視したい特定のシナリオがありますが、この警告により、少なくともそれが起こっていることを知ることができます.あなたの場合、メッセージは意図したアプリケーションによって処理されていない.

したがって、これを修正するには、エンドポイント名を変更するだけです。MySubscriber と MyPublisher、またはそのようなもの。

その属性を使用する必要さえありません。実装するクラスに名前を付けるだけでIConfigureThisEndpoint、NServiceBus はそれに基づいてエンドポイント名を構築します。などのアンダースコアを使用することもできMyProject_MyPublisher : IConfigureThisEndpoint、NServiceBus はアンダースコアをドットに変換するため、"MyProject.MyPublisher" の入力キューを取得できます。これは、多数のエンドポイントが実行されている場合の名前空間に非常に適しています。

于 2012-09-05T17:47:58.133 に答える