RabbitMQのManagementプラグインでメッセージを読み出してみた
2019-10-23
azblob://2022/11/11/eyecatch/2019-10-23-rabbitmq-get-massages-000.jpg

はじめに

以前、RabbitMQを通してメッセージを手動で送信する方法を解説しました。

RabbitMQのManagementプラグインには手動でメッセージを作成して送信する機能があるので、これを利用すれば普段は何かしら別のコンポーネントからメッセージをPublishしなければ動作を試せないという問題を解決できます。

さて、それでは、普段はこのメッセージキューの中をどのようなメッセージが流れているのでしょうか?

前回はメッセージキューに送信するメッセージを指定しましたが、あの形式で送信すればメッセージが正しく処理されるとなぜわかるのでしょうか?

今回は、この疑問を解決し、以前のメッセージ送信の方法の記事と合わせて、メッセージキューの受信側だけで動作を試せるようにしたいと思います。

前提

「RabbitMQのManagementプラグインからメッセージを流してみた」の記事で解説したサンプルが作成できている

メッセージの読み出し方

まずは前回作成したProgram.csの中身に変更を加えます。

using System;
using MassTransit;

namespace massTransitEx
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var bus = Bus.Factory.CreateUsingRabbitMq(sbc =>
            {
                var host = sbc.Host(new Uri("rabbitmq://localhost"), h =>
                {
                    h.Username("guest");
                    h.Password("guest");
                });

//                sbc.ReceiveEndpoint(host, "TestQueue",
//                    ep =>
//                    {
//                        ep.Handler<ExClass>(context => { return Console.Out.WriteLineAsync(context.Message.Message); });
//                    });
            });
            bus.Start();

            bus.Publish(new ExClass(){Message = "Hello RabbitMQ!"});
        }
    }
}

変更点としては、メッセージキューの受け取りを行っていた部分をコメントしたことと、メッセージをPublish(送信)する部分を追加したことです。

これによって、処理されることのないメッセージが1個だけ送信されてメッセージキュー上にとどまり続けることになります。

なので、これからこのメッセージを読み出しに行きます。

コードが変更できたら、まずはRabbitMQとManagementを立ち上げます。

サンプルのアプリケーションをビルド&Runします。

Management画面にログインします。

Queuesタブに移動し、TestQueueを選択します。

下のメニューから、Get messagesを開き、Get Message(s)のボタンを押します。

うまくいけば、下記のようなPayloadを含んだメッセージを取得できます。
一部分は環境によって変わるのでマスクしています。

{

  "messageId": "000d0000-2700-0a00-2365-08d755bec029",

  "conversationId": "000d0000-2700-0a00-dd56-08d755bec034",

  "sourceAddress": "[メッセージの作成元のアドレスがここに表示されます]",

  "destinationAddress": "[メッセージの送り先のアドレスがここに表示されます]",

  "messageType": [

    "urn:message:massTransitEx:ExClass",

    "urn:message:MassTransit:IConsumer"

  ],

  "message": {

    "message": "Hello RabbitMQ!"

  },

  "sentTime": "[メッセージを送信した時刻がここに表示されます]",

  "headers": {},

  "host": {

    "machineName": "[発信元のマシンの名前がここに表示されます]",

    "processName": "dotnet",

    "processId": 17608,

    "assembly": "[このメッセージが送信された元のコンポーネントのアセンブリ名が表示されます]",

    "assemblyVersion": "1.0.0.0",

    "frameworkVersion": "4.0.30319.42000",

    "massTransitVersion": "6.0.0.0",

    "operatingSystemVersion": "[OSのバージョン名がここに入ります]"

  }

}

このようにすれば、MessageQueueを通るメッセージを取得して中身を読み出すことができます。

実際には、メッセージをPublishする側だけを起動してメッセージを送信させ、それをこの方法で読み出すことでメッセージのフォーマットを知ることができ、それによってフォーマットに沿って別のメッセージを作成して送信することができるようになります。

また、余談ですが、ここで受信したメッセージと以前の記事で紹介した送信するメッセージの内容は違っています。

具体的には、送信用のメッセージは今回読み出したメッセージよりかなり内容が少ないです。

これは、メッセージとして送信される情報のうち、すべての情報が処理に必須なわけではないためです。

今回の場合だと、messageTypeとmessageの内容があれば正常に処理されました。

messageの型とその内容さえ情報として持っていればメッセージは正常に処理されるようです。

まとめ

この方法は同じチームの先輩から教えてもらったものなのですが、これを知ってからメッセージを受け取って動作するコンポーネントの動作のチェックが随分と楽になりました。コンポーネントを二つも走らせることによるコンピュータへの負荷が減り、開発がかなり捗るようになりました。

最近はイベント駆動やメッセージ駆動でアプリケーション間通信を実装することもあるため、この方法は知っておくと役に立つように思います。

お役に立てられれば幸いです。