こんにちは、サイオステクノロジー技術部 武井です。前回はDurable Functions入門編と題しまして、Durable Functionsの簡単なサンプルを交えまして、概要についてご説明致しました。
※全シリーズの記事一覧はこちら
- 多分わかりやすいDurable Functions 〜サーバーレスは次のステージへ〜【入門編】
- 今回はこちら → 多分わかりやすいDurable Functions 〜サーバーレスは次のステージへ〜【実践編】
- 多分わかりやすいDurable Functions 〜サーバーレスは次のステージへ〜【理論編】
- 多分わかりやすいDurable Functions 〜サーバーレスは次のステージへ〜【番外編】
今回の実践編では、より複雑なユースケースを例に挙げて、「Durable Functionsを使わない場合」と「Durable Functionsを使った場合」のコードの差を比較することで、Durable Functionsの素晴らしさをお伝えすることができたらと思います。
今回のユースケース
以下のようなユースケースを想定します。
- 指定された複数のWebサイトのRSSタグを取得して、「Azure」というタグが含まれる記事の合計件数を算出する。
- 各WebサイトのRSSタグの取得・合計件数の算出は並列で実行する。
上記の内容を、「Durable Functionsを使わない場合」と「Durable Functionsを使った場合」で比較したいと思います。
「Azure」というタグの抽出対象に利用させて頂くWebサイトは以下の2つです。
- https://tech-lab.sios.jp/:弊社の技術ブログ「SIOS Tech.Lab」です。
- https://satonaoki.wordpress.com/:「週アズ」こと「週刊アジュール」で有名な、マイクロソフトのエバンジェリストさとうなおき様のブログです。Azureの有用な記事がたくさんありますので、今回利用させて頂きましたm(_ _)m
今回、この2つのブログのRSSタグを「Azure」という単語で検索し、その記事数を合計するという処理を並列に実施して、最後に各ブログの合計数をさらに合計して、2つのブログ全体での「Azure」という単語が含まれる記事数の合計を算出します。
Durable Functionsを使わない場合
まずは、先の要件をDurable Functionsを使わずに実現をしてみます。このアプリケーションを構成する要素は以下になります。
Azure Functions |
集計対象のWebサイトのRSSタグを取得し、「Azure」という単語が含まれる記事の合計数を算出します。このAzure Functionsは後述するAzure Queue Storageでトリガーされ、その結果は、これまた後述するAzure Table Storageに格納します。 |
Azure Queue Storage |
先程ご紹介したAzure Functionsは、Azure Queue Storageでトリガーされます。そのメッセージが格納されるキューになります。 |
Azure Table Storage | 先程ご紹介したAzure Functionsは、Webサイトごとの集計結果を、AzureのキーバリューストアであるAzureTable Storageに返します。 |
C#で書いたアプリ | Azure Queue Storageにメッセージをプッシュしたり、Azure Table Storageに格納された結果を集計したりするアプリケーションです。 |
文字だけの説明ですと中々わかりにくいかと思いますので、マンガ形式で図を交えてご説明致します。
■ その1:Azure Table StorageとAzure Queue Storageへの登録
まず最初に、C#で書いたアプリが、Azure Table Storageにレコードを登録します。これは集計対象のURLごと行います。テーブル構成は以下のとおりです。
Partition Key |
集計対象のWebサイトをグルーピングする任意のID |
RowKey |
集計対象のWebサイトのURL(実際はbase64エンコードしている) |
Status |
集計対象のWebサイトの処理状況を表すステータス(processingは処理中、successは処理完了) |
Count | 集計対象のWebサイトで、「Azure」というタグが含まれる記事の数 |
次にC#で書いたアプリが、Azure Queue Storageにメッセージを登録します。これは集計対象のURLごとに行います。今回の例であれば、2つのWebサイトを集計対象にしますので、2つのメッセージを登録し、そのフォーマットは以下になります。
{ "jobId":"53726358", "url":"https://tech-lab.sios.jp/feed/" }
jobIdはAzure Table StorageのPartitionKeyに登録した値と同じ、urlは集計対象のWebサイトのURLです。
■ その2:Azure Functionsの起動
Azure FunctionsはQueueトリガーなので、Azure Queue Storageにメッセージが入ると、Azure Functionsが実行されます。
■ その3:Azure Functionsによる集計処理及び結果の返却
Azure FunctionsはメッセージのJSONのurlフィールドから集計処理のRSSタグのURLを取得して、Azureという単語が含まれる記事の数を取得します。今回の場合、Azure Queue Storageには、集計対象のURLごとに2つのメッセージが入ってくるので、同時に2つのAzure Functionsが起動して、並列で2つのWebサイトのRSSタグを修正することになります。
集計した結果は、Azure Table Storageに返却します。PartitionKey(JSONのjobIdフィールド)とRowKey(集計対象のURLでJSONのurlフィールドをbase64エンコードしたもの)をキーに、Statusをsuccessに、Countに集計結果を登録します。
■ その4:Azure Functionsによる集計処理及び結果の返却(2つ目のサイト)
今回の集計対象である2つのWebサイトのうちの、もう一方も先程と同様の処理を実施します。
■ その5:合計の取得
C#で書いたアプリが、定期的にAzure Table Storageをチェックし、同じPartitionKeyのStatusが全てsuccessになったら、Countの値を合計します。つまりこれは、集計対象のWebサイトの記事の中でAzureという単語が含まれる記事の数を集計するというAzure Functionsの終了を待っているということを意味します。そして、全てのAzure Functionsが終了したら、そのCountを合計すれば、それは集計対象のWebサイトの記事の中でAzureという単語が含まれる記事の合計数ということになります。
以上が処理の流れになります。
そして、これより先のシステムを実現するためのソースコードをご紹介致します。
まず、「C#で書いたアプリ」のソースコードです。
次にAzure Functionsのソースコードです。
いかがでしょうか?結構長いソースコードになっています。次章では、これをDurable Functionsで実現することで、どれだけソースコードがシンプルになるかをご説明致します。
Durable Functionsを使う場合
次にDurable Functionsを使う場合のソースコードをご紹介します。クライアント関数、オーケストレーター関数、アクティビティ関数の構成は前回ご紹介したとおりです。
「Durable Functionsを使わない場合」でご紹介したような、Azure Queue StorageやAzure Table Storageの用意は必要ありません。「C#で書いたアプリ」のように、仮想マシンやApp Service上での動作が想定されるC#アプリケーションも不要です。上記のコードのみで全く同じ動作をする上に、ソースコードもかなりシンプルになっております。もちろん、サーバーレスです。
すごいですね、Durable Functions。癖になりそうです。
まとめ
前回のブログで、Durable Functionsの特徴を以下のようにご紹介致しました。
Azure Functionsだけで実現しようとすると、ものすごく複雑なコードになってしまうような複雑な処理が、Durable Functionsを使うと、すごく短いコードで簡単に実現できる。しかもサーバーレスで。
まさに今回の例で、体感頂けたかと思います。今回ご紹介した機能は、Durable Functionsが持つもののほんの一部です。
もっと活用して、Durable Functionsマニアになりたいです。
次回は、Durable Functionsの内部的な動きをご説明したいと思います。