AzureのService Busについて

Microsoft AzureにService Busというサービスがあります。

このサービスをできるだけ簡単にご紹介したいと思います。

何ができる?

伝えたいメッセージを確実に相手に伝えるサービスです。

商品を販売するシステムと、売れた商品を梱包して発送するシステムがあった場合、両者をうまく機能させるには連携させる必要があります。

うまく連携させるには、販売するシステムと梱包して発送するシステムがそれぞれの状況に応じて処理できるようにする必要があります。

例えば、商品が売れたタイミングで梱包して発送するシステムが休みだった場合。

梱包して発送するシステムが忙しい場合。

これらの場合は、商品の販売状況に影響しないように、売れたことを相手に確実に伝える必要があります。

また、梱包して発送する側は、処理できる状況になったときに販売状況を確認して処理できるようにする必要があります。

これを実現するのが、Service Busです。

Service Busは、メッセージを受け取ると一旦そのメッセージをため込みます。

受け取る相手がメッセージを要求した時点でメッセージを渡して削除します。

メッセージを送る側、メッセージを受け取る側のそれぞれの状況に応じて処理ができるので、全体的にスムーズに処理を行うことができます。

メッセージのやりとりのタイプは2種類

メッセージのやりとりのタイプは2種類あります。

キュー

メッセージを送信された順に送ります。

この時、メッセージを送る側、メッセージを受け取る側は複数であっても構いません。

トピック

1:nでのメッセージのやりとりで使います。

送ったメッセージは、予め決められたルートに乗り配信されます。各ルートにはフィルタを設定でき、受け取り側が必要なメッセージだけを受け取ることができます。

Pub/Subのメッセージングとも言われますが、MQTTなどのPub/Subとは処理が異なり、1つのメッセージを受信できるのは1つだけです。

メッセージは受信したら削除されますので、他の受信者が受信することはできません。

Service Busはトランザクションをメッセージで相手に伝えると言うことを前提にしているのでこのようになっています。

トランザクションなので、受信側で処理を終えたものを別の受信者が受け取って同じ処理をしたらおかしくなると言うことを防ぐことができます。

使い方

Azureの管理コンソールで、Service Busを作成します。

価格レベルがBasicの場合は、トピックが使えません。

キューを使う場合はキューを作成します。

トピックを使う場合はトピックと受信するサブスクリプションを作成します。

メッセージをやりとりする

.Net、Java、Node.jsなど主要な言語でメッセージを送信、受信するプログラムを作成できます。

Node.jsでトピックを使った送信、受信についてご紹介します。

@azure/service-busパッケージのインストール

まずは、@azure/service-busパッケージをインストールします。

npm install @azure/service-bus --save

送信側のプログラム

トピックの共有アクセスポリシーを作成し、プライマリ接続文字列を取得します。

メッセージを10回送信するプログラムです(send.js)

connectionStringに共有アクセスポリシーのプライマリ接続文字列を、topicNameに作成したトピック名を設定します。

const { ServiceBusClient } = require("@azure/service-bus"); 

// Define connection string and related Service Bus entity names here
const connectionString = "<<共有アクセスポリシーのプライマリ接続文字列>>";
const topicName = "pitadigi-test-topic"; 

async function main(){
  const sbClient = ServiceBusClient.createFromConnectionString(connectionString); 
  const topicClient = sbClient.createTopicClient(topicName);
  const sender = topicClient.createSender();

    try {
        for (let i = 0; i < 10; i++) {
          const message= {
            body: `Hello world! to-a ${i}`,
            label: `test`,
            to: `to-a`,
            userProperties: {
                myCustomPropertyName: `my custom property value ${i}`
            }
          };
          console.log(`Sending message: ${message.body}`);
          await sender.send(message);
        }
      }

        await topicClient.close();
      } finally {
        await sbClient.close();
      }
}

main().catch((err) => {
  console.log("Error occurred: ", err);
});

以下のように実行するとメッセージを送信できます。

node send.js

受信側のプログラム

メッセージを受信するプログラムです(recieve.js)

connectionStringに共有アクセスポリシーのプライマリ接続文字列を、topicNameに作成したトピック名、subscriptionNameに作成したサブスクリプション名を設定します。

const { ServiceBusClient, ReceiveMode } = require("@azure/service-bus"); 

// Define connection string and related Service Bus entity names here
const connectionString = "<<共有アクセスポリシーのプライマリ接続文字列>>";
const topicName = "pitadigi-test-topic"; 
const subscriptionName = "pitadigi-test-topic-sub"; 

async function main(){
  const sbClient = ServiceBusClient.createFromConnectionString(connectionString); 
  const subscriptionClient = sbClient.createSubscriptionClient(topicName, subscriptionName);
  const receiver = subscriptionClient.createReceiver(ReceiveMode.receiveAndDelete);

  try {
    while(true) {

    const messages = await receiver.receiveMessages(1);
    console.log("Received messages:");
    console.log(messages.map(message => message.body));
    }

    await subscriptionClient.close();
  } finally {
    await sbClient.close();
  }
}

main().catch((err) => {
  console.log("Error occurred: ", err);
});

以下のように実行すると先に送信したメッセージを10個受信できることが分かります。

node recieve.js

送信と受信のプログラムは非常にシンプルです。

最近では、サービスを分けて、それぞれを連携することで一連の処理を行うケースが増えています。

このようなときには、とても役立つService Busです。

Service Busに関する詳細はMicrosoftのサイトをご覧ください。