Partager via


Microsoft Azure WebJobs SDK の 0.4.0-beta プレビューを発表

このポストは、8 月 21 日に投稿した Announcing the 0.4.0-beta preview of Microsoft Azure WebJobs SDK の翻訳です。

マイクロソフトはこのたび、Microsoft Azure WebJobs SDK プレビューの新しいバージョンをリリースしました。WebJobs SDK については Scott Hanselman 氏がこちらの記事 (英語) で紹介しています。また、以前のバージョンの詳細についてはこちらの記事を参照してください。

今回のリリースでは、0.3.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

パッケージ名が 0.3.0-beta から変更されたため、今回は最新バージョンへの更新を支援するリダイレクト パッケージをアップロードしています。

 Update-Package Microsoft.Azure.Jobs.Core –Pre
 Update-Package Microsoft.Azure.Jobs –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 が新しいデータを受け取るたびに、コードに記述されている関数を呼び出します。

今回のプレビューで更新された点

非同期のサポート

関数の中で async と await を使用し、関数から Task を戻すことができます。

1 つの JobHost 内の複数の関数が並行して実行されます。つまり、異なる Queue をリッスンする 2 つの関数がある場合、それらが並行して実行されるということです。

次のコードは、関数内で async と await を使用して Task を戻す方法を示しています。この関数は、Azure Queues 上の inputqueue というメッセージでトリガーされ、そのメッセージを BLOB に書き込みます。

 class Program
{
    static void Main()
    {
        JobHost host = new JobHost();
        host.RunAndBlock();
    }
   public async static Task HelloWorldFunctionAsync(
   [QueueTrigger("inputqueue")] string inputText,
   [Blob("output/output.txt")] TextWriter output)
   {
       await output.WriteAsync(inputText);
   }
}

またオプションで、関数の引数として CancellationToken を受け取ることもできます。たとえば、次の関数は「input」というコンテナー内で新しい BLOB が検出されるとトリガーされ、CancellationToken を CopyToAsync 関数に渡すことができます。また、この関数は SDK がファイル名と拡張子をどのようにバインドするかも示しています。SDK を使用すれば、ファイル名や拡張子に簡単にアクセスできます。

 class HelloWorldAsyncCancellationToken
{
    static void Main()
    {
        JobHost host = new JobHost();
        host.RunAndBlock();
    }
    public async static Task ProcessBlob(
    [BlobTrigger("input/{name}.{extension}")] Stream input,
    string name, // SDK が File の名前をバインド
    string extension, // SDK が File の拡張子をバインド
    [Blob("output/{name}.{extension}", FileAccess.Write)] Stream output,
    CancellationToken token)
    {
        await input.CopyToAsync(output, 4096, token);
    }
}

関数は明示的に呼び出すことができます。これは、Azure Scheduler を使用してスケジュールで WebJob を実行する場合や、単純に関数を呼び出す場合に便利です。この方法でも、診断や、長時間実行されている関数のキャンセルといった SDK の便利な機能は活用できます。

 class Program
{
    static void Main()
    {   
        JobHost host = new JobHost();
        Task callTask = host.CallAsync(typeof(Program).GetMethod("ManualTrigger"), 
                                      new { value = 20 });

        Console.WriteLine("Waiting for async operation...");
        callTask.Wait();
        Console.WriteLine("Task completed: " + callTask.Status);
    }

    [NoAutomaticTrigger]
    public static void ManualTrigger(
    TextWriter log, int value, [Queue("outputqueue")] out string message)
    {
        log.WriteLine("Function is invoked with value={0}", value);
        message = value.ToString();
        log.WriteLine("Following message will be written on the Queue={0}", message);
    }
}

Azure Queues 内の有害メッセージの処理

0.3.0-beta の SDK では、Queue の DequeueCount プロパティにバインドするオプションがありましたが、今回のリリースではメッセージが自動的に有害な Queue に移動されるようになりました。

これにより、有害メッセージを調査のためにログに記録するなど、アプリケーション コード内で処理できるようになりました。方法は単純に関数を QueueTrigger("Queue 名-poison") にバインドするだけです。

次のコードはこの Queue のメッセージを処理しています。Queue にバインドされている関数の処理中に例外が発生した場合、SDK はメッセージを 5 回 (既定) 処理するとそのメッセージを有害と見なし、メッセージを別の Queue に移動します。

 class ProcessPoisonMessages
{
    static void Main()
    {
        JobHost host = new JobHost();
        host.RunAndBlock();
     }
     public async static Task ProcessQueue(
     [QueueTrigger("inputqueue")] string inputText,
     [Blob("output/output.txt")] TextWriter output)
     {
       await output.WriteAsync(inputText);
     }
     public static void ProcessPosionQueue(
     [QueueTrigger("inputqueue-poison")] string inputText)
     {
       //有害メッセージを処理し、ログに記録するか、通知を送る
     }
}

Azure Queues に対するポーリング ロジックの改良

今回のリリースでは新しいポーリング戦略が採用されました。アイドル時の Queue のポーリングによるストレージ トランザクション コストへの影響を減らすために、SDK にはランダムな指数バックオフ アルゴリズムが実装されています。

Queue の高速な通知

  • 0.3.0-beta の SDK は最大 2 秒間隔でポーリングを行っていました。つまり、20 個の関数が連続するチェーン (1 つの関数が Queue に書き込みを行い、これがトリガーとなって次の関数が Queue に書き込みを行い、またこれが次の関数のトリガーとなる、という処理が繰り返される) の場合、20 個のメッセージの処理には最大で 40 秒かかりました。今回の変更により、これは最大 8 秒に短縮されます。

Queue のポーリングの構成オプション

新しい SDK では、Queue のポーリング動作を開発者が構成できるようにいくつかの設定オプションが提供されています。

  • MaxPollingInterval: Queue を空にしたまま、メッセージを確認せずに待機する最長の時間。既定値は 10 分です。
  • MaxDequeueCount: Queue メッセージを有害な Queue に移動するタイミング。既定値は 5 です。

次のコードはこれらの設定を構成する方法を示しています。

 static void Main()
{
       JobHostConfiguration config = new JobHostConfiguration();
       config.Queues.MaxDequeueCount = 3;
       config.Queues.MaxPollingInterval = TimeSpan.FromMinutes(20); 
       JobHost host = new JobHost(config);
       host.RunAndBlock();
 }

パッケージおよび名前空間の変更

一般的な語「Job」と区別しやすくするためにパッケージ名を変更しました。「Job」は混同しやすく、検索も困難でした。

この変更を取り込むには、既存アプリケーションの再コンパイルと ConnectionString の変更が必要です。

アセット

変更前

変更後

パッケージ

Microsoft.Azure.Jobs

Microsoft.Azure.WebJobs

 

Microsoft.Azure.Jobs.Core

Microsoft.Azure.WebJobs.Core

 

Microsoft.Azure.Jobs.ServiceBus

Microsoft.Azure.WebJobs.ServiceBus

名前空間

Microsoft.Azure.Jobs

Microsoft.Azure.WebJobs

ConnectionString 名

AzureJobsStorage

AzureWebJobsStorage

 

AzureJobsDashboard

AzureWebJobsDashboard

 

ダッシュボード インデックス処理の高速化

すべての WebJob を表示する場合や WebJob の関数の詳細を表示する場合のダッシュボードのパフォーマンスが向上しました。

ダッシュボードのデータが古いことを警告

ダッシュボードで、ホスト データがバックグラウンドで処理されるようになりました。大量の作業が残っている場合には警告が表示されます。

ダッシュボード インデックスのエラー

インデックスのエラーがある場合、ダッシュボードの [About] ページに表示されるようになりました。ダッシュボードがログのインデックス付けに失敗している場合、このページでエラーの発生を確認できるので便利です。

バグの修正

今回のリリースで多くのバグが修正されました。フォーラムや StackOverflow で報告されたバグを優先的に修正しています。

 

SDK の既存の機能

0.3.0-beta に引き続き今回のリリースでもサポートしている機能は次のとおりです。

Azure の使用

今回の SDK では、Azure Blobs、Queues、Tables、Service Bus 用のトリガーとバインディングが追加されています。

トリガー

Queue または BLOB 上で新しい入力が検出されたときに関数を実行できます。トリガーの詳細については、こちらの記事 (英語) を参照してください。

バインディング

この SDK ではバインディングがサポートされており、C# プリミティブ型と、BLOB、Table、Queue といった Azure Storage との間でモデル バインディングを行います。これにより、BLOB、Table、Queue のデータを読み書きする処理が簡単になり、Azure Storage に対して読み書きを実行するコードを開発者が習得する必要がなくなります。

現在、Stream TextReader/Writer String のバインディングがサポートされています。また、カスタム型や Storage SDK のその他の型へのバインディングのサポートを追加することが可能です。詳細については、後述のサンプルを参照してください。

ホスティング

JobHost は、プログラムに含まれる関数を認識している実行コンテナーです。JobHost オブジェクト (Microsoft.Azure.WebJobs (英語) から使用) は、バインディングを読み取り、トリガーをリッスンし、関数を呼び出します。次の例では、JobHost のインスタンスを作成し RunAndBlock() を呼び出します。これにより、JobHost はこのホストに定義された関数に対するすべてのトリガーをリッスンするようになります。

 static void Main()
{
    JobHost host = new JobHost();
    host.RunAndBlock();
}

WebJob の監視用ダッシュボード

WebJob (言語、型を問わない) の実行中にリアルタイムで監視を行い、WebJob の状態 (Running、Stopped、Successfully completed)、最終実行日時、実行ログを確認することができます。次のスクリーンショットのように、WebSites で稼動するすべての WebJob が表示されます。

関数実行の詳細

「ImageProcessing」という WebJob の実行を監視する場合、プログラム内の関数呼び出しに関して次のような詳細情報を確認できます。

  • この関数のパラメーター
  • 関数の実行所要時間
  • BLOB からの読み取りの所要時間と、読み書きのバイト数

ImageProcessing WebJob のコードは次のとおりです。この WebJob が使用している機能を以下に説明します。

 using Microsoft.Azure.WebJobs;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Helpers;

namespace ImageResizeAndWaterMark
{
    class ImageProcessingFunctions
    {
        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(@"images2-newoutput/{name}")] out WebImage output)
        {
            output = input.AddTextWatermark("WebJobs is now awesome!!!!", fontSize: 6);
        }
    }
    public class WebImageBinder : ICloudBlobStreamBinder<WebImage>
    {  
        public Task<WebImage> ReadFromStreamAsync(Stream input, CancellationToken cancellationToken)
        {
            return Task.FromResult(new WebImage(input));
        }

        public async Task WriteToStreamAsync(WebImage result, Stream output, CancellationToken cancellationToken)
        {
            var bytes = result.GetBytes();
            await output.WriteAsync(bytes, 0, bytes.Length,cancellationToken);
        }
    }
}

呼び出しと再実行

上の例では、Resize 関数が何らかの理由で正常に動作しない場合、新しい画像をアップロードして Resize 関数を再実行できます。すると実行チェーンがトリガーされ、Watermark 関数も呼び出されます。このような詳細情報は、関数どうしが複雑に組み合わされている場合に問題を診断してデバッグするのに便利です。また、ダッシュボードから関数を実行することも可能です。

関数の因果関係

上の例では、Resize 関数が BLOB への書き込みを行うと、それがトリガーとなって WaterMark 関数が呼び出されます。ダッシュボードには、このような関数間の因果関係が表示されます。多数の関数が複雑に絡み合い、新しい入力が検出されるたびにトリガーされるような場合に、この因果関係グラフが役立ちます。

BLOB の検索

[Search Blobs] をクリックし BLOB を検索すると、該当する BLOB で発生した事象に関する情報を確認できます。たとえば、ImageProcessing の場合は Resize 関数が実行されるので、BLOB に対する書き込みが行われています。BLOB の検索の詳細については、こちらの記事 (英語) を参照してください。

 

サンプル

WebJobs SDK のサンプルは次の場所を参照してください。https://github.com/Azure/azure-webjobs-sdk-samples (英語)

  • BLOB、Table、Queue、および Service Bus でのトリガーやバインディングの使用例をご覧いただけます。
  • PhluffyShuffy というサンプルは画像処理を行う Web サイトです。ユーザーがここに写真をアップロードすると、BLOB ストレージのその画像を処理する関数がトリガーされます。

関連資料

SDK を使用した WebJob のデプロイ

Visual Studio 2013 Update 3 および Azure SDK 2.4 では、WebJob を Azure WebSites に公開する Visual Studio ツールのサポートが追加されています。詳細については、「Azure WebJob を Azure WebSites にデプロイする方法 (英語)」を参照してください。

0.3.0-beta から 0.4.0-beta への移行時の既知の問題

新しい API に合わせた名前空間の更新

変更前
Microsoft.WindowsAzure.Jobs
Microsoft.Azure.Jobs.Core

変更後Microsoft.WindowsAzure.WebJobs
Microsoft.Azure.WebJobs.Core

connectionString 名の更新

connectionString を設定する際、WebJob の app.config または Microsoft Azure WebSites の [Configure Tab] で connectionString の名前を、次のように変更する必要があります。

変更前AzureJobsRuntime
AzureJobsDashboard

変更後AzureWebJobsRuntime
AzureWebJobsDashboard

connectionString のログアカウントへの保管

最新バージョンの SDK (0.4.0-beta) までは、AzureJobsRuntime ストレージ アカウントの接続文字列が AzureJobsDashboard ログに保管されます。このログを表示できるのは管理ユーザーのみであり、接続文字列を表示およびリセットできるユーザーと同じです。これは大きな問題とはなっていませんが、今後このような運用は取り止めます。今後 1 か月の間に、ダッシュボードを更新してこれまでに保管された接続文字列を削除する予定です。

今すぐに接続文字列を削除するには、AzureJobsDashboard connectionString で指定されたログを開きます。

"azure-jobs*" という名前の BLOB コンテナー名を削除します (ただし、"azure-jobs-host"、"azure-jobs-host-output"、"azure-jobs-host-archive"、"azure-jobs-dashboard" は除きます)。

"AzureJobs*" という名前のテーブルを削除します。

"azure-jobs*" という名前の Queue を削除します。

ダッシュボードは 0.4.0-beta でデプロイされた WebJob にのみ対応

WebJob を 0.3.0-beta の SDK でデプロイしている場合、ダッシュボードでその WebJob のログを確認すると、「Host not running」という警告が表示されます。これは、今回のリリースにより最新バージョンのダッシュボードがすべての Azure WebSites にデプロイされることが原因です。新しいダッシュボードはプロトコルが若干変更されており、0.3.0-beta との互換性がありません。このエラーを回避するには 0.4.0-beta NuGet パッケージを使用するよう WebJob を更新し、WebJob を再度デプロイしてください。

フィードバックとヘルプについて

Microsoft Azure WebSites の WebJob 機能と Microsoft Azure WebJobs SDK は現在プレビュー版です。このプレビュー版の改良に役立つフィードバックをぜひご提供ください。

このチュートリアルに直接的には関係のないご質問は、Azure フォーラムASP.NET フォーラム (英語)、または StackOverflow.com (英語) までお寄せください。Twitter の場合は #AzureWebJobs SDK を付けてフィードバックをお願いします。StackOverflow では「Azure-WebJobsSDK」タグをご使用ください。