BLOGAzureブログ
メッセージキューイングをレガシーと侮るなかれ、クラウドインフラの界隈では必須と言っても過言ではない!そうだAzure Service Busを使おう
Azure相談センターSB C&Sは、Microsoft Azureを推奨します。
メッセージキューイングをレガシーと侮るなかれ、クラウドインフラの界隈では必須と言っても過言ではない!そうだAzure Service Busを使おう
皆さまこんにちは、SB C&Sの八釼(やつるぎ)です。
メッセージキューイング(MQ)というデータを送受信する手法をご存じでしょうか?メインフレームの時代から使われてきた実績のある技術なのですが、肌感覚的には10年くらい前からは耳にすることがめっきり減ったと感じており、この時期からIT業界に足を踏み入れた方には馴染みが薄いのではないでしょうか。ちなみに私が以前営業していたアプリケーション(商材)のシステムでも採用されていました。懐かしい。
ですがこのMQは決して遺物のような存在ではなく、むしろ現代(クラウドインフラが当たり前の時代)では積極的に活用すべきものなのです。なぜかというと、疎結合アーキテクチャとしてシステムを設計することが基本的には求められるからです。人気が高まっているソフトウェアアーキテクチャ(デザインパターン)の一種であるマイクロサービスは、アプリ(コンポーネント)を疎結合で独立に展開可能な小さな要因に分割するアーキテクチャのアプローチですよね。クラウドコンピューティングは利用状況に応じて柔軟かつ迅速にサービスを拡張・縮小できるので相性が良いわけです。
ということで、今回はMQが関連するAzure Service Busについての概要をご紹介します。
詳細については公式ドキュメントをご確認いただければと思いますが、細かなことはさておきざっくりメッセージ配信サービスです。複数の異なるアプリケーション、システム、ドメインにおいて、(主に非同期で)相互に通信を行うために活用されます。
やはりリソースを作成して動かしてみないとなかなかイメージが湧かないので、Azure Service Bus キューとの間でメッセージを送受信する (Python)というクイックスタートを実施してみます。
なお、今回は割愛しますがキューではなくトピックとサブスクリプションというエンティティを使用して、発行者(送信者)1に対してサブスクライバー(受信者)は多数という形式の通信を行うこともできます。
このクイックスタートのようにAzure Portalから作成してデプロイしても良いですし、Bicep ファイルを使用して Service Bus の名前空間とキューを作成するというクイックスタートのようにBicepコードを書いてコマンドラインからデプロイするなどでも構いません。
ちなみに私は後者でデプロイしました。コードをそのままコピペでBicepファイルを作成してしまえば、問題なくデプロイが成功するので楽だからです。詳細は割愛しますが以下のパラメーターの値を使いました。
param serviceBusNamespaceName string = 'licensecounter-blog-serviceBusNamespace'
param serviceBusQueueName string = 'licensecounter-blog-serviceBusQueue'
リソースグループについては以下のように定義し作成しました。
param resourceGroupName string = 'licensecounter-blog-servicebus-rg'
param resourceGroupLocation string = 'japaneast'
なお、すべてのリソースは東日本リージョン(japaneast)にしました。
これでキューも含めて必要になるリソースはすべてデプロイできました。
メッセージをキューに送信するアプリと受信するアプリ(二つのファイル)を作成します。
今回は検証だし楽なので接続文字列を使用することにしました。念のためですが、この記事ではこの文字列をソースコードに直書き(ハードコーディング)しますので、実際に本番運用アプリケーションシステムの場合にはパスワードレスを選択しこのようなハードコーディングは避けましょう。
それはさておき、Service Bus の名前空間に接続するためのプライマリ接続文字列を取得します。
キューにメッセージを送信するアプリを作成します。
ただ、難しく考える必要はないです。クイックスタートのコードをコピーして貼り付けるだけです。これでsend.pyの出来上がりです。
もちろん、さきほど取得したプライマリ接続文字列(NAMESPACE_CONNECTION_STR
)とキューの名前(QUEUE_NAME
)の値は置き換えが必要です。
import asyncio
from azure.servicebus.aio import ServiceBusClient
from azure.servicebus import ServiceBusMessage
NAMESPACE_CONNECTION_STR = "Endpoint=sb://licensecounter-blog-servicebusnamespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
QUEUE_NAME = "licensecounter-blog-servicebusqueue"
async def send_single_message(sender):
# Create a Service Bus message and send it to the queue
message = ServiceBusMessage("Single Message")
await sender.send_messages(message)
print("Sent a single message")
async def send_a_list_of_messages(sender):
# Create a list of messages and send it to the queue
messages = [ServiceBusMessage("Message in list") for _ in range(5)]
await sender.send_messages(messages)
print("Sent a list of 5 messages")
async def send_batch_message(sender):
# Create a batch of messages
async with sender:
batch_message = await sender.create_message_batch()
for _ in range(10):
try:
# Add a message to the batch
batch_message.add_message(ServiceBusMessage("Message inside a ServiceBusMessageBatch"))
except ValueError:
# ServiceBusMessageBatch object reaches max_size.
# New ServiceBusMessageBatch object can be created here to send more data.
break
# Send the batch of messages to the queue
await sender.send_messages(batch_message)
print("Sent a batch of 10 messages")
async def run():
# create a Service Bus client using the connection string
async with ServiceBusClient.from_connection_string(
conn_str=NAMESPACE_CONNECTION_STR,
logging_enable=True) as servicebus_client:
# Get a Queue Sender object to send messages to the queue
sender = servicebus_client.get_queue_sender(queue_name=QUEUE_NAME)
async with sender:
# Send one message
await send_single_message(sender)
# Send a list of messages
await send_a_list_of_messages(sender)
# Send a batch of messages
await send_batch_message(sender)
asyncio.run(run())
print("Done sending messages")
print("-----------------------")
次にrecv.pyも同様に作成します。
が、少々注意することがあります。(私が参照した時点での)クイックスタートではrevc.pyを作成せよと指示がありますが、これは誤記載です。正しくは、recv.pyです。英単語的にもcvの並びなはずですよね。
ちなみに私はこの間違いに気が付かずアプリ実行の工程でエラーが出ました。それでこれに気付いたのでした。
import asyncio
from azure.servicebus.aio import ServiceBusClient
NAMESPACE_CONNECTION_STR = "Endpoint=sb://licensecounter-blog-servicebusnamespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
QUEUE_NAME = "licensecounter-blog-servicebusqueue"
async def run():
# create a Service Bus client using the connection string
async with ServiceBusClient.from_connection_string(
conn_str=NAMESPACE_CONNECTION_STR,
logging_enable=True) as servicebus_client:
async with servicebus_client:
# get the Queue Receiver object for the queue
receiver = servicebus_client.get_queue_receiver(queue_name=QUEUE_NAME)
async with receiver:
received_msgs = await receiver.receive_messages(max_wait_time=5, max_message_count=20)
for msg in received_msgs:
print("Received: " + str(msg))
# complete the message so that the message is removed from the queue
await receiver.complete_message(msg)
asyncio.run(run())
必要なPythonパッケージをインストールした後、以下のコマンドをソースコードファイルが格納されているディレクトリにて実行します。
python send.py; python recv.py
まずsend.pyを実行し、その後recv.pyを実行するということです。
すると以下が出力されました。コマンドを実行している端末から16(1+5+10)メッセージを送信して、16メッセージを同端末にて受信しましたね。
Sent a single message
Sent a list of 5 messages
Sent a batch of 10 messages
Done sending messages
-----------------------
Received: Single Message
Received: Message in list
Received: Message in list
Received: Message in list
Received: Message in list
Received: Message in list
Received: Message inside a ServiceBusMessageBatch
Received: Message inside a ServiceBusMessageBatch
Received: Message inside a ServiceBusMessageBatch
Received: Message inside a ServiceBusMessageBatch
Received: Message inside a ServiceBusMessageBatch
Received: Message inside a ServiceBusMessageBatch
Received: Message inside a ServiceBusMessageBatch
Received: Message inside a ServiceBusMessageBatch
Received: Message inside a ServiceBusMessageBatch
Received: Message inside a ServiceBusMessageBatch
念のためAzure portalでも確認してみると、名前空間の概要画面ページでもキューの概要画面ページでも、受信メッセージ数と送信メッセージ数が16になっていることを確認できました。
ちなみに、しっかりと(細かく)この記事を読んでくださった方であれば前述の誤記載を正さなくともこの実行コマンドで実際の受信アプリのファイル名を指定すれば問題ないことに気付かれたかと思います。ただこういった演習を行う際にはテキストに忠実にやるのが基本ですのでエラーが出て少々焦ってしまうかもしれません。
今回はAzure Service Busについてご紹介させていただきましたが、似たようなサービスとしてAzure Queue Storageというものもあります。どちらが良い悪いというわけではなく、要件によって使い分けることになります。一つだけわかりやすく特徴的な機能の違いをお伝えしますと、Service Bus ではFIFO(先入れ先出し)キューを用いてメッセージの送受信順序を保持することができます。
また他にも似たようなものとして、イベントの配信やストリーミングのサービスもあります。
ややこしいですが、何となくのサービス名やこのようなものがあるということはぜひ覚えておきましょう。
Azureのメッセージングサービスを使用するアプリケーション開発にあたっては色々とお困りごとが出てくるかもしれませんが、その際にはぜひとも法人でのAzure導入前の相談窓口であるAzure相談センターまでお気軽にお問い合わせいただけますと幸いです。弊社では、ユーザー様のご状況やご要望を踏まえて最適な形でのAzureの導入のご支援を提供しており、Azure に精通したスタッフが丁寧にご回答いたします。
Azureの導入や運用に関するお悩みは SoftBankグループのSB C&Sにご相談ください
SoftBankグループのSB C&Sは、さまざまな分野のエキスパート企業との協力なパートナーシップによって、多岐にわたるAzure関連ソリューションをご提供しています。
「Azureのサービスを提供している企業が多すぎて、どの企業が自社にベストか分からない」
「Azure導入のメリット・デメリットを知りたい」
「Azureがどういう課題を解決してくれるのか知りたい」
など、Azureに関するお悩みならお気軽にお問い合わせください。
中立的な立場で、貴社に最適なソリューションをご提案いたします。
クラウドサーバーご検討中の方必見
お役立ち資料一覧
そのようなお悩みはありませんか?
Azure相談センターでは、上記のようなお悩みを解決する
ダウンロード資料を豊富にご用意しています。
是非、ご覧ください。
オンプレミスからクラウドへの移行を検討している方のために、安心・スムーズな移行を実現する方法を解説し、
運用コストの削減に有効な「リザーブドインスタンス」もご紹介するホワイトペーパーです。
導入から活用まで専門スタッフが回答いたします。
お気軽にお問い合わせください。