Microsoft Azure WebJobs SDK の 1.0.0-rc1 を発表
このポストは、9 月 22 日に投稿された Announcing the 1.0.0-rc1 of Microsoft Azure WebJobs SDK の翻訳です。
マイクロソフトはこのたび、Microsoft Azure WebJobs SDK プレビューの新しいバージョンをリリースしました。WebJobs SDK については Scott Hanselman 氏がこちらで紹介 (英語) しています。以前のバージョンの詳細については、こちらの発表記事 (英語) (翻訳 - SATO NAOKI ブログ : Microsoft Azure WebJobs SDKの0.6.0-betaプレビューの発表) を参照してください。
今回のリリースは 0.6.0-beta と同じ基本機能に、バグの修正が加えられています。
このリリースをダウンロードする
WebJobs SDK は、NuGet のギャラリーからダウンロードできます。NuGet ギャラリーで NuGet Package Manager Console を使用して、パッケージをインストールまたは更新します。
Install-Package Microsoft.Azure.WebJobs –Pre
Microsoft Azure Service Bus のトリガーを使用したい場合は、次のパッケージをインストールします。
Install-Package Microsoft.Azure.WebJobs.ServiceBus -Pre
WebJobs SDK とは
Microsoft Azure WebSites の WebJob は、サービスやバックグラウンド タスクなどのプログラムを WebSites で簡単に実行できるようにするための機能で、.exe、.cmd、.bat などの各種実行形式ファイルを WebSites にアップロードしたり、実行したりすることができると同時に、WebJob としてトリガーで実行したり継続的に実行したりすることができます。WebJobs SDK なしでバックグラウンド タスクの接続や実行を行うとなると、複雑で膨大な量のプログラミングが必要になりますが、SDK が提供するフレームワークを使用すれば、最低限の量のコードで一般的なタスクを実行することが可能になります。
WebJobs SDK のバインディング システムとトリガー システムは、Service Bus だけでなく、Microsoft Azure Storage サービスの BLOB、Queue、Table にも対応しています。バインディング システムでは、Microsoft Azure Storage オブジェクトを読み込んだり書き込んだりするコードを簡単に作成できます。トリガー システムは、Queue または BLOB が新しいデータを受信するたびに、コードに記述されている関数を呼び出します。
WebJobs SDK のシナリオ
Azure WebJobs SDK を使用すると容易に対応できる、代表的なシナリオをいくつか紹介します。
- ž画像処理などの CPU 負荷の高い作業。
- ž電子メール送信など、バックグラウンドのスレッドで実行する処理に長い時間がかかるタスク。このようなタスクは、アプリケーションが一定時間以上アイドル状態だと IIS がアプリケーションをリサイクルするため、従来は ASP.NET では不可能でした。しかし、Azure WebSites に AlwaysOn (英語) (翻訳 - SATO NAOKI ブログ : Webサイト向けのステージング発行のサポート、監視の改善、Hyper-V Recovery ManagerのGA、PCIコンプライアンス) が導入されたため、アイドル状態でも WebSites のリサイクルを防げるようになりました。AlwaysOn (英語) (翻訳 - SATO NAOKI ブログ : Webサイト向けのステージング発行のサポート、監視の改善、Hyper-V Recovery ManagerのGA、PCIコンプライアンス) は、サイトがスリープ状態にならないように維持することができるため、処理に長い時間がかかるタスクやサービスを WebJob や WebJobs SDK で実行できます。
- žQueue の処理。Web のフロントエンド サービスとバックエンド サービスの通信には Queue を使用するのが一般的です。よくある Producer-Consumer パターンの 1 つです。
- žRSS 情報集約。RSS フィードのリストを保持するサイトを所有している場合、バックグラウンド プロセスでフィードからすべての記事を取得することがあります。
- žファイルのメンテナンス。ログ ファイルの集約や整理など。
- 受信処理。CSV リーダー、ログの解析、Table へのデータの格納など。
SDK の目的
- Azure Storage を使用してバックグラウンド処理を容易に行えるようにする手段を提供すること。
- žアプリケーションで容易に Azure Storage を使用できるようにすること。SDK を利用すれば、ストレージからのデータの読み書きを行うコードを作成する必要はありません。
- ž診断やログ出力用のコードを開発することなく使用できる、リッチな診断機能と監視機能を提供すること。
今回のプレビューで更新された点
今回のプレビューの変更点は、バグの修正のみです。機能自体には前回から変更はありません。次に、今回のリリースで追加された重要な動作上の変更点を紹介します。
BLOB を Stream にバインディングする場合に FileAccess パラメーターが必要に
今回のリリース以降、BLOB 属性を使用して Stream にバインディングする場合に FileAccess パラメーターの設定が必要になりました。
public static void BindingToBlob(
[BlobTrigger("container/input")] Stream input,
[Blob("container/output", FileAccess.Write)] out Stream output
)
{
}
MaxPollingInterval の既定値の変更
この設定は、Queue のメッセージを確認するまでに待機する最長の時間を指定するために使用します。
これまでの既定値は 10 分でしたが、今回より 1 分に変更になりました。この変更は、既定の Queue のプロセスの応答性を高めることを目的としています。
Stream ではなく String を使用してメッセージを使用した場合に Service Bus トリガーは機能しない
次の方法で Service Bus メッセージを作成した場合、関数はトリガーされません。
var triggerMessage = new BrokeredMessage("Text");
JSON.NET の最低バージョンを 6.0.4 に更新
QueueTrigger メッセージまたは BlobTrigger メッセージへのバインディング
SDK では、Queue や BLOB で関数がトリガーされた場合に、Queue メッセージや BLOB パスにバインディングすることができます。次のコードは、queueTrigger または blobTrigger にバインディングしてメッセージにアクセスし、そのメッセージをバインディングに使用する方法を示しています。
このコードは、処理が完了した BLOB を削除する一般的なクリーンアップ関数を示しています。BlobToQueueForCleanup 関数の blobTrigger には、BLOB パスが指定されています (SDK によって blobTrigger に BLOB の完全なパスが入力されています)。関数の処理が完了すると、「deleteblob」という Queue に BLOB パスが送信されます。
新しいメッセージが「deleteblob」に送信されると、Cleanup 関数がトリガーされ、queueTrigger にバインディングします (SDK によって queueTrigger にメッセージの内容が入力されています)。その後、CloudBlockBlob にバインディングして BLOB を削除します。
public static void BlobToQueueForCleanup(
[BlobTrigger("input/{name}")] TextReader reader, string blobTrigger,
[Queue("deleteblob")] out string blobToDelete)
{
blobToDelete = blobTrigger;
}
public static void Cleanup(
[QueueTrigger("deleteblob")] string blobToDelete, string queueTrigger,
ICloudBlob blob)
{
blob.Delete();
}
BLOB の名前と拡張子へのバインディング
次のように BLOB の名前と拡張子にアクセスする関数を使用する場合、名前とは拡張子の前までを指します (パスのサブディレクトリを含む)。
たとえば、BLOB パスが「input/foo.bar.baz.txt」の場合、名前は「foo.bar.baz」で拡張子は「txt」になります。BLOB パスが「input/foo/bar/baz.txt」の場合は、名前が「foo/bar/baz」で拡張子が「txt」になります。
public static void BlobBinding(
[BlobTrigger("input/{name}.{extension}")] TextReader input, string name,string extension,
[Blob("output/{name}_old.{extension}",FileAccess.Write)] TextWriter writer
)
{
writer.Write(input.ReadToEnd());
}
存在しないエンティティへのバインディング
今回のリリース以降、存在しないエンティティはスローされずに、null 値が渡されるようになりました。たとえば、次のコードではリーダーが存在しない場合に null 値が渡されます。
public static void BlobBinding(
[QueueTrigger("blobname")] string input, string queueTrigger,
[Blob("input/{queueTrigger}", FileAccess.Read)] Stream reader
)
{
//リーダーは null
}
}
これと同じ動作には、他にも次のような例があります。
- 常に null 参照 (Stream、TextReader、String) を呼び出す
- žオブジェクトをバインディングする場合に ICloudBlobStreamObjectBinder に null Stream を渡す
- žSDK 型 (CloudBlockBlob、CloudPageBlob、CloudTable、CloudQueue) に参照を渡す
- Table、Queue、BLOB コンテナーが存在しない場合に作成する
- žIQueryable によって空の Queryable が返される
注 : 次のセクションでは、今回のリリースで利用可能な機能の概要を紹介します。
SDK の機能
トリガー
Queue または BLOB で新たな入力が検出されると、関数が実行されます。
バインディング機能
この SDK ではバインディング機能がサポートされており、C# プリミティブ型と、BLOB、Table、Queue、Service Bus といった Azure Storage の間でモデル バインディングを行います。これにより、BLOB、Table、Queue からデータを読み書きする処理が簡単になり、Azure Storage からの読み書きを実行するコードを開発者が習得する必要がなくなります。
- 利便性: 最も使いやすい型を選択すると、WebJobs SDK がグルー コードとして働きます。BLOB で文字列操作を行う場合、TextWriter への変換方法を気にすることなく、直接 TextReader および TextWriter にバインドできます。
- žフラッシュとクローズ: WebJobs SDK は、未処理の出力を自動的にフラッシュおよびクローズします。
- žユニットテストが可能: この SDK は、ICloudBlob などではなく TextWriter などのプリミティブ型のモックとして動作させることができるため、作成したコードのユニット テストが可能です。
- ž診断機能: ダッシュボードから使用可能なモデル バインディング機能により、パラメーターの使用状況をリアルタイムで診断できます。
現在 Stream 、 TextReader/Writer 、 String のバインディングがサポートされています。カスタム型や Storage SDK のその他の型へのバインディングのサポートを追加することが可能です。
Azure Queues
SDK を使用して、Queue に新しいメッセージが送信された場合に関数をトリガーすることができます。String、Poco (Plain old CLR object)、byte[]、Azure Storage SDK の各型にバインディングすることにより、メッセージの内容に簡単にアクセスできます。次に、Queue で使用できるその他の主要な機能を紹介します。
詳細については、0.5.0-beta、0.4.0-beta、0.3.0-beta の発表記事を参照してください。
- 関数をトリガーして、メッセージの内容を String, Poco (Plain old CLR object)、byte[]、CloudQueueMessage にバインディングします。
- 単一または複数のメッセージを Queue に送信します。
- Queue の並列実行: 1 つの QueueTrigger 内で、並行して Queue の複数のメッセージがフェッチされます。つまり、関数が Queue をリッスンしている場合、この Queue に対して 16 個 (既定値) の Queue のメッセージのバッチが並行して取得されます。また、関数も並行して実行されます。
- Azure Queues の有害メッセージの処理
- Queue の DequeueCount プロパティへのアクセス
- Azure Queues のポーリング ロジックの改良: ストレージのトランザクション コストに対するアイドル時の Queue のポーリングの影響を減らすために、SDK にはランダムな指数バックオフ アルゴリズムが実装されています。
- 高速なパスの通知: SDK を使用して複数の Queue にメッセージを送信する場合、SDK によってメッセージの高速追跡が実行されます。0.3.0-beta では、約 2 秒間隔でポーリングが実行されていました。つまり、アプリで 20 個の関数のチェーン (1 つの関数が Queue に書き込み、これがトリガーとなって次の関数が Queue に書き込み、またこれが次の関数のトリガーとなる、という処理の繰り返し) を使用していた場合、20 個のメッセージを処理するために約 40 秒かかりました。これまでの変更により、この時間は現在約 8 秒に短縮されています。
- Queue のポーリングの構成オプション: Queue のポーリング動作を構成できるように、数点のオプションが用意されています。
- MaxPollingInterval は、Queue が空の状態が続く場合に、メッセージを確認するまでに待機する最長の時間を指定するために使用します。既定値は 1 分です。
- MaxDequeueCount は、Queue のメッセージを有害な Queue に移動するタイミングを指定するために使用します。既定値は 5 です。
Azure Blobs
SDK を使用して、新しい BLOB が検出された場合や、既存の BLOB が更新された場合に、関数をトリガーすることができます。Stream、String、Poco (Plain old CLR object)、byte[]、TextReader、TextWriter、Azure Storage SDK の各型にバインディングすることにより、BLOB の内容にアクセスできます。
詳細については、0.5.0-beta、0.4.0-beta、0.3.0-beta の発表記事を参照してください。
- BlobTrigger は、新しい BLOB が検出された場合または既存の BLOB が更新された場合にのみトリガーされます。
- ž BLOB の再試行およびエラー処理: BLOB の処理時にエラーが発生した場合に、関数の再試行がサポートされています。BlobTrigger では、指定した回数の上限に達するまで処理を再試行します (既定値は 5 回)。しきい値に達して関数が 5 回実行されると、「webjobs-blobtrigger-poison」という Queue にメッセージが送信されます。この Queue の QueueTrigger を使用して関数をトリガーし、メッセージに対してカスタムのエラー処理を実行することができます。
Azure Storage Tables
SDK を使用して、Table にバインディングし、読み取り、書き込み、更新、削除の操作を実行することができます。
詳細については、0.6.0-beta (英語) (翻訳 - SATO NAOKI ブログ : Microsoft Azure WebJobs SDKの0.6.0-betaプレビューの発表)、0.5.0-beta、0.4.0-beta、0.3.0-beta の発表記事を参照してください。
受信処理は、BLOB に格納されたファイルを解析し、値を CSV リーダーなどの Table に格納する場合の一般的なシナリオです。このような場合、Ingress 関数によって多数の行 (場合によっては何百万もの行) が書き込まれる可能性があります。
WebJobs SDK では、この機能を簡単に実装し、Table に書き込まれた行数などをリアルタイムで監視する機能を追加することができるため、Ingress 関数の進捗状況を監視することができます。
次の関数は、Azure Storage Tables に 100,000 行を書き込む方法を示しています。
public static class Program
{
static void Main()
{
JobHost host = new JobHost();
host.Call(typeof(Program).GetMethod("Ingress"));
}
[NoAutomaticTrigger]
public static void Ingress([Table("Ingress")] ICollector<Person> tableBinding)
{
// 多数の行の受信処理をシミュレーションするには、ループ処理を使用します。
// この部分は、Blob Storage から読み込み、Azure Tables に書き込むための
// 独自のロジックに置き換えてください。
for (int i = 0; i < 100000; i++)
{
tableBinding.Add(
new Person()
{ PartitionKey = "Foo", RowKey = i.ToString(), Name = "Name" }
);
}
}
}
public class Person
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public string Name { get; set; }
}
Azure Service Bus
Azure Queues と同様に、SDK を使用して、新しいメッセージが Service Bus Queue またはトピックに送信された場合に関数をトリガーすることができます。String、Poco (Plain old CLR object)、byte[]、BrokeredMessage にバインディングすることにより、メッセージの内容に簡単にアクセスできます。
詳細については、0.3.0-beta の発表記事を参照してください。
全般
次に、SDK のその他の有用な機能の一部を紹介します。
- 非同期のサポート : async 関数がサポートされています。
- CancellationToken: 関数に CancellationToken パラメーターを使用して、ホストからキャンセルのリクエストを受信できます。
- NameResolver: SDK の拡張レイヤーでは、Queue 名または BLOB 名のソースを指定することができます。たとえば、この機能を使用して、構成ファイルから Queue 名を取得できます。このサンプル (英語) をご覧ください。
- WebJob シャットダウン通知 : WebJob の正常なシャットダウン (Graceful Shutdown、英語) 通知機能では、WebJob が停止するときに通知が表示されます。SDK では、キャンセルのトークンを使用して、この通知を関数に伝達します。SDK は WebJob がシャットダウンするタイミングをユーザーに通知することで、WebJob の正常なシャットダウンをサポートします。この情報は CancellationToken により関数に伝えられます。次の関数は、WebJob が停止すると CancellationToken を通じてキャンセルのリクエストを受信します。
public static void UseCancellationToken(
[QueueTrigger("inputqueue")] string inputText,
TextWriter log,
CancellationToken token)
{
// 長い時間がかかる関数をキャンセルすることが可能
while (!token.IsCancellationRequested)
{
Thread.Sleep(2000);
log.WriteLine("Not cancelled");
}
log.WriteLine("cancelled");
}
WebJob の監視用ダッシュボード
WebJob の実行中は、任意の言語で作成された任意の型でリアルタイムの監視が可能です。これにより、WebJob の状態 (Running、Stopped、Successfully completed)、最終実行日時、実行ログを確認できます。次の画面で WebSites で稼動するすべての WebJob を確認できます。
この SDK を使用して WebJob を作成すると、プログラム内の関数の診断と監視を行えます。ここで、画像処理を行う「ImageResizeAndWaterMark」という名前の WebJob を作成した場合について考えます。フローは次のようになります。
まず、ユーザーが画像を BLOB の「images-input」というコンテナーにアップロードすると、Resize 関数がトリガーされます。Resize はこの画像を処理した後に「images2-output」コンテナーに書き込みます。ここで Watermark 関数がトリガーされ、画像のサイズ変更が実行された後に「images3-output」という BLOB コンテナーに書き込まれます。次のコードは、上記で説明した WebJob を示しています。
public class ImageProcessing
{
public static void Resize(
[BlobTrigger(@"images-input/{name}")] WebImage input,
[Blob(@"images2-output/{name}")] out WebImage output)
{
var width = 80;
var height = 80;
output = input.Resize(width, height);
}
public static void WaterMark(
[BlobTrigger(@"images2-output/{name}")] WebImage input,
[Blob(@"image3-output/{name}")] out WebImage output)
{
output = input.AddTextWatermark("WebJobs", fontSize: 6);
}
}
public class WebImageBinder : ICloudBlobStreamBinder<WebImage>
{
public Task<WebImage> ReadFromStreamAsync(Stream input, System.Threading.CancellationToken cancellationToken)
{
return Task.FromResult<WebImage>(new WebImage(input));
}
public Task WriteToStreamAsync(WebImage value, Stream output, System.Threading.CancellationToken cancellationToken)
{
var bytes = value.GetBytes();
return output.WriteAsync(bytes, 0, bytes.Length);
}
}
WebJob を Azure で実行しているときに Microsoft Azure WebSites のポータルで [WEBJOBS] タブの「ImageResizeAndWaterMark」というログへのリンクをクリックすると、WebJob のダッシュボードが表示されます。
ダッシュボードは SiteExtension なので、https://<自身のサイト>.scm.azurewebsites.net/azurejobs という URL でアクセスできます。SiteExtension にアクセスするには、デプロイメントの認証情報が必要です。SiteExtension へのアクセスの詳細については、Kudu プロジェクトのドキュメントをお読みください。
https://github.com/projectkudu/kudu/wiki/Accessing-the-kudu-service (英語)
関数実行の詳細
「ImageResizeAndWaterMark」という WebJob の実行を監視する場合、プログラム内の関数呼び出しに関する次のような詳細情報を確認できます。
- 関数のパラメーターの種類
- 関数の実行時間
- BLOB からの読み込みの所要時間と読み書きのバイト数
呼び出しと再実行
上の例では、WaterMark 関数が何らかの理由で正常に動作しない場合、新しい画像をアップロードして WaterMark 関数を再実行すると、実行チェーンがトリガーされ、Resize 関数が呼び出されます。これは、関数どうしが複雑に組み合わされている場合に問題を診断してデバッグするのに便利です。また、ダッシュボードからも関数を呼び出すことができます。
関数の因果関係
上の例では、WaterMark 関数が BLOB への書き込みを行うと、Resize 関数がトリガーされます。ダッシュボードでは、この関数の因果関係が表示されます。多数の関数が複雑に絡み合い、新しい入力が検出されるたびにトリガーされるような場合に、この因果関係グラフが役立ちます。
BLOB の検索
[Search Blobs] をクリックし BLOB を検索すると、該当する BLOB で発生した事象に関する情報を確認できます。たとえば、ImageResizeAndWaterMark の場合は WaterMark 関数が実行されると、BLOB に対する書き込みが行われます。BLOB の検索の詳細については、こちらの記事 (英語) を参照してください。
サンプル
WebJobs SDK のサンプルについては、次のページをご覧ください。
https://github.com/Azure/azure-webjobs-sdk-samples (英語)
- BLOB、Table、Queue、および Service Bus でのトリガーやバインディングの使用例をご覧いただけます。
- PhluffyShuffy というサンプルでは、画像処理を行う Web サイトでユーザーが写真をアップロードすると、BLOB ストレージのその画像を処理する関数がトリガーされます。
チュートリアル: Azure WebJobs SDK の使用を開始する (英語)
このチュートリアルにしたがって、WebJobs SDK の使用を開始することができます。
関連資料
- Channel 9 ビデオ: Azure WebJobs SDK で仕事を便利に (英語)
- Scott Hanselman 氏による WebJob と SDK の紹介 (英語)
- Brady Gaster 氏 (英語) による WebJob と ASP.NET を使用した Web サイト モニターの構築に関する記事 (英語)
- Azure の WebJob に関する参考資料 (英語)
- Azure Friday の WebJob ビデオ シリーズ (英語)
SDK を使用した Azure WebSites への WebJob のデプロイ
Visual Studio 2013 Update 3 と Azure SDK 2.4 では、WebJob を Azure WebSites に発行する Visual Studio ツールがサポートされています。詳細については、Azure Websites への Azure WebJob のデプロイ方法 (英語) を参照してください。
0.6.0-beta から 1.0.0-rc1 への移行時の既知の問題
BLOB を Stream にバインディングする場合に FileAccess パラメーターが必要
今回のリリース以降、Blob 属性を使用して Stream にバインディングする場合に FileAccess パラメーターの設定が必要になりました。
public static void BindingToBlob(
[BlobTrigger("container/input")] Stream input,
[Blob("container/output", FileAccess.Write)] Stream output
)
{
}
Azure Storage SDK (CloudBlockBlob 、 CloudPageBlob 、 ICloudBlob など ) へのバインディング
既定の FileAccess は Read ではなく、ReadWrite です。その他のオプションを選択することはできません。
フィードバックとヘルプについて
Microsoft Azure WebSites の WebJob (英語) 機能と Microsoft Azure WebJobs SDK は現在プレビュー版です。皆様からの改善のためのフィードバックをお待ちしています。
チュートリアルに直接関係のないご質問は、Azure フォーラム、ASP.NET のフォーラム (英語)、または StackOverflow.com (英語) までお寄せください。Twitter は #AzureWebJobs をお付けください。StackOverflow ではタグ「Azure-WebJobsSDK」をご使用ください。