2016-09-29 12 views
2

バスにコンシューマがないC#とRabbitMQを使用して、MassTransit v3でパブリッシュ専用バスを実装しようとしています。このコンセプトは、メッセージが公開され、キューに入れられると、別のマイクロサービスがキューからメッセージを消費します。 this SO answerを見ると、メッセージが実際にキューに入れられるように受信エンドポイントを指定する必要があります。しかし、これはcontradict the common gotchas in the MassTransit docsに現れ、If you need to only send or publish messages, don’t create any receive endpointsと書かれています。 、私は予想通りRabbitMQのキュー内のメッセージが表示され、これは、コンソールにHello Worldのを書き込みMyConsumerによって消費され、メッセージが続いている。このサンプルでC#とRabbitMQでMassTransit v3でパブリッシュ専用バスを実装

public class Program 
    { 
     static void Main(string[] args) 
     { 
      var bus = BusConfigurator.ConfigureBus(); 

      bus.Start(); 

      bus.Publish<IItemToQueue>(new ItemToQueue { Text = "Hello World" }).Wait(); 

      Console.ReadKey(); 

      bus.Stop(); 
     } 
    } 

    public static class BusConfigurator 
    { 
     public static IBusControl ConfigureBus() 
     { 
      var bus = Bus.Factory.CreateUsingRabbitMq(cfg => 
      { 
       var host = cfg.Host(new Uri("rabbitmq://localhost/"), hst => 
       { 
        hst.Username("guest"); 
        hst.Password("guest"); 
       }); 

       cfg.ReceiveEndpoint(host, "queuename", e => 
       { 
        e.Consumer<MyConsumer>(); 
       }); 
      }); 

      return bus; 
     } 
    } 

    public interface IItemToQueue 
    { 
     string Text { get; set; } 
    } 

    public class ItemToQueue : IItemToQueue 
    { 
     public string Text { get; set; } 
    } 

    public class MyConsumer : IConsumer<IItemToQueue> 
    { 
     public async Task Consume(ConsumeContext<IItemToQueue> context) 
     { 
      await Console.Out.WriteLineAsync(context.Message.Text); 
     } 
    } 

:ここ

は、いくつかのサンプルコードですキューから削除されました。私は上から以下のコードを削除したときに

しかし、サンプルを再実行します。

一時キューは、(生成された名前を持つ)を作成し、メッセージが決してに配置されるように思われていない
cfg.ReceiveEndpoint(host, RabbitMqConstants.ValidationQueue, e => 
{ 
    e.Consumer<MyConsumer>(); 
}); 

一時的なキュー。バスが停止すると、このキューは削除されます。

ReceiveEndpointが指定されていると、パブリッシャプログラムのキューからメッセージが消費され、削除されます(コンシューママイクロサービスがキューに入れられたアイテムを処理しないことを意味します)。 RecieveEndpointが指定されていないと、一時的なキューが使用され(消費者のマイクロサービスはこの一時的なキューの名前を知らない)、メッセージはキューに入らず、キューが停止したときに削除され、プログラムがダウンした。

an example of a send only bus in the MassTransit docsがありますが、それはかなり基本的なので、私は誰にも何か提案があったのだろうかと思っていましたか?

+0

パブリッシャ/送信者にエンドポイントを受け取る必要はありませんが、どこかにメッセージが必要な場合や、メッセージ交換にバインドされているキューがない場合でも、メッセージはどこにもルーティングされずに送信されます。 –

答えて

1

受信エンドポイントは、公開専用アプリケーションとは別のサービス内にある必要があります。このようにして、サービスは受信エンドポイントを持ち、アプリケーションによって公開されるときにメッセージを消費します。

アプリケーションに受信エンドポイントがある場合、受信エンドポイントで指定されたキュー名が同じであるため、アプリケーションはメッセージを消費します。

同じ構成(受信エンドポイントを含む)で別のサービスを作成し、受信エンドポイントをアプリケーションから取り除くだけで、必要な作業を行うことができます。その時点で、サービスは受信エンドポイントを持ち、キューからのメッセージを消費します。サービスが停止しても、メッセージはキューに引き続き配信され、サービスが開始されると消費が開始されます。

+0

最初はRabbitMQを設定するだけですか?私は同様の状況にあり、受信側のキューが保存され、最終的に処理される限り、その時点でサービスが起動していても、アプリケーションがメッセージの送信を開始するとすぐに受信キューがメッセージを受信することを保証する必要があります。サービスを一度実行すると、この要件を満たすように設定されても、それは問題ありません。これは、ドキュメントがいくつかの例を使用できる領域です。これがうまくいくとすれば、私はそれを書いてうれしいです。 –

+0

これについてGitHubに問題があります。基本的にRabbitMQでトポロジを作成しないでください。あなた自身がアプローチするワイヤから来る問題は、タイプシステムの微妙なニュアンスが手動で正しくセットアップされず、起動時にエラーが発生する可能性があるということです。ただし、特定のキューに送信する場合は、送信者が交換をキューにバインドするためのクエリ文字列パラメータがあります。これはbindまたはbindQueue = trueのいずれかです。ありがとう。 –

+0

ありがとう。問題のリンクを提供できますか?私はついに今朝行くことができました。消費者と一緒に一度立ち上げた後、私はそれを取り除いて、その後の実行でもメッセージを保持することができました。私はdev/exploreモードで、明らかにプロダクションのための計画ではありません:)私は考えていたタイプとバージョン管理に関するいくつかの質問を提起しますが、もう少しプレイした後の別の投稿の対象です。 –

関連する問題