CRON in the Cloud:新しいWindows Azureスケジューラタスクスケジューラサービスの完全ガイド

画像



Windows Azureのスケジュールされたタスクは、 モバイルサービススケジューラー 、Quartzスケジューラー、 FluentSchedulerWebBackgrounderScheduledEnqueueTimeUtcなど、ジョブを適切に実行するのに役立つ既成のソリューションを備えた興味深いトピックでした。 これらのオプションは正常に使用できますが、実際には、クラウドサービスまたはWebサイトの役割に基づいて実行されるWindows Azureアプリケーション専用に設計されていません。



このため、ほぼ1年前、Aditiは新しいサービス-スケーラブルなタスクスケジューラを発表しました。これは、Windows Azureで実行されるアプリケーションのニーズを満たすために特別に構築されたものです。 Aditi Schedulerは、Windows Azureチームの伝説であるRyan Dunnによって作成されました。 数か月前、このサービスは500,000のタスクを祝い、Windows Azureストレージキューのサポートを追加しました。



しかし、Microsoftは最近、新しいWindows Azure SchedulerサービスであるAditi Schedulerの優れた代替手段を発表しました。



Windows Azureスケジューラを使用すると、スケジュールに従って、HTTP / S要求やストレージキューへのメッセージ送信など、さまざまなアクションを実行できます。 スケジューラを使用して、クラウドインフラストラクチャの内部と外部の両方でサービスを呼び出すことが保証されているタスクをクラウドで作成できます。 これらのタスクは、オンデマンドで、またはスケジュールに従って定期的に実行できます。また、将来のある日付の実行をスケジュールできます。


新しいサービスをもっとよく知りましょう。



プレビューサービスを有効にする



現在、Windows Azureスケジューラサービスはプレビューとして利用できます。そのため、予備サービスのページ( http://www.windowsazure.com/en-us/services/preview/)でサブスクライブする必要があります







サービス管理は、Windows Azure管理ポータルではまだ利用できません。 スケジューラと対話する唯一の方法は、オープンなREST APIを使用するか、既製のSDKを使用することです。 サービスAPIの詳細については、MSDNの「 スケジューラREST APIリファレンス」セクションを参照してください。



SDKのインストール



スケジューラSDKは、NuGetパッケージ(最初のバージョン)として入手でき、少し前にリリースされた新しいWindows Azure管理ライブラリの一部です。 まず、パッケージをインストールする必要があります。

PM>インストールパッケージMicrosoft.WindowsAzure.Management.Scheduler –Pre

はじめに



新しい機能をすばやくテストするために、Windows Azureの発行設定ファイル( こちらからダウンロードできます)を使用しました。 次のクラスは、ファイルからデータを抽出し、それに基づいてCertificateCloudCredentialsオブジェクトを作成します。これは、管理ライブラリで作業するときに認証に使用できます。



public static class CertificateCloudCredentialsFactory { public static CertificateCloudCredentials FromPublishSettingsFile(string path, string subscriptionName) { var profile = XDocument.Load(path); var subscriptionId = profile.Descendants("Subscription") .First(element => element.Attribute("Name").Value == subscriptionName) .Attribute("Id").Value; var certificate = new X509Certificate2( Convert.FromBase64String(profile.Descendants("PublishProfile").Descendants("Subscription").Single().Attribute("ManagementCertificate").Value)); return new CertificateCloudCredentials(subscriptionId, certificate); } }
      
      





このクラスの使用は非常に簡単なタスクです。



 var publishSettingsFilePath = @"D:\\azdem.publishsettings"; var subscriptionName = "Azdem194D92901Y"; var credentials = CertificateCloudCredentialsFactory .FromPublishSettingsFile(publishSettingsFilePath, subscriptionName);
      
      





タスクスケジューラサービスはクラウドサービス(クラウドサービス)で実行されるため、クラウドサービスの作成から始めました。 現時点では、1つの点を考慮する必要があります:作成されたクラウドサービスは、Windows Azureスケジューラサービスがサポートされているリージョンに配置する必要があります(プレビュー段階では、サポートは一部のリージョンのみに制限されますが、残りはサービスが商用運用になったときに追加されます)。



 var cloudServiceClient = new CloudServiceManagementClient(credentials); var result = cloudServiceClient.CloudServices.Create("sandrino-cs1", new CloudServiceCreateParameters() { Description = "sandrino-cs1", GeoRegion = "north europe", Label = "sandrino-cs1" }); Console.WriteLine(result.Status); Console.WriteLine(result.HttpStatusCode);
      
      





タスクスケジューラリソースプロバイダーの登録



クラウドサービスには、仮想マシン(IaaS)とWebロールまたは作業ロール(PaaS)の両方を含めることができることが知られています。 ただし、クラウドサービスにWindows Azureスケジューラなどの「リソースプロバイダー」を含めることができるようになりました。クラウドサービスで同様のリソースプロバイダーを使用するには、まずそれを有効にする必要があります定期購入:これを行わないと、次のエラーが発生します:

Microsoft.WindowsAzure.Management.Scheduler.dllで「Microsoft.WindowsAzure.CloudException」タイプの未処理の例外が発生しました



追加情報:ForbiddenError:サブスクリプションにはリソースを使用する権利がありません

次に、タスクスケジューラプロバイダーを登録しましょう(登録はサブスクリプション全体に対して有効です):



 var schedulerServiceClient = new SchedulerManagementClient(credentials); var result = schedulerServiceClient.RegisterResourceProvider(); Console.WriteLine(result.RequestId); Console.WriteLine(result.StatusCode); Console.ReadLine();
      
      





リソースプロバイダーを登録すると、そのプロパティを要求できるようになります。



 var schedulerServiceClient = new SchedulerManagementClient(credentials); var result = schedulerServiceClient.GetResourceProviderProperties(); foreach (var prop in result.Properties) { Console.WriteLine(prop.Key + ": " + prop.Value); } Console.ReadLine();
      
      





たとえば、次のコードを使用すると、サービスで利用可能な使用計画と、サービスが動作できる地域を見つけることができます。







ジョブコレクション



次のステップでは、「ジョブコレクション」を作成します。これは、タスクを保存するためのコンテナであり、タスクにさまざまなクォータを適用するためのメカニズムです。 さらに、これは無料または有料のサービス使用レベルを選択する必要がある場所です。

タスクコレクションにはタスクのグループが含まれ、コレクション内のすべてのタスクに共通の設定、クォータ、および制限を管理します。 タスクのコレクションは、サブスクリプションの所有者によって作成され、消費またはアプリケーションの境界に基づいてタスクを結合します。 タスクのコレクションは1つの領域に制限されています。 また、コレクション内のすべてのタスクの消費メトリックにMaxJobsおよびMaxRecurrenceクォータを設定できます。

両方のプランで使用できるクォータの詳細については、 http//msdn.microsoft.com/en-us/library/windowsazure/dn479786.aspxのリンクを参照してください



 var schedulerServiceClient = new SchedulerManagementClient(credentials); var result = schedulerServiceClient.JobCollections.Create("sandrino-cs2", "jobcoll001", new JobCollectionCreateParameters() { Label = "jobcoll001", IntrinsicSettings = new JobCollectionIntrinsicSettings() { Plan = JobCollectionPlan.Standard, Quota = new JobCollectionQuota() { MaxJobCount = 100, MaxJobOccurrence = 100, MaxRecurrence = new JobCollectionMaxRecurrence() { Frequency = JobCollectionRecurrenceFrequency.Minute, Interval = 1 } } } }); Console.WriteLine(result.RequestId); Console.WriteLine(result.StatusCode); Console.ReadLine();
      
      





HTTP(S)タスクとストレージキュー



タスクのコレクションができたので、スケジューラーのタスクの作成を開始できます。 現在、タスクスケジューラは、HTTP、HTTPS、およびストレージキューの3種類のタスクをサポートしています。 最初にhttpサポートを見てみましょう。



 var schedulerClient = new SchedulerClient(credentials, "sandrino-cs2", "jobcoll001"); var result = schedulerClient.Jobs.Create(new JobCreateParameters() { Action = new JobAction() { Type = JobActionType.Http, Request = new JobHttpRequest() { Body = "customer=sandrino&command=sendnewsletter", Headers = new Dictionary() { { "Content-Type", "application/x-www-form-urlencoded" }, { "x-something", "value123" } }, Method = "POST", Uri = new Uri("http://postcatcher.in/catchers/527af9acfe325802000001cb") } }, StartTime = DateTime.UtcNow, Recurrence = new JobRecurrence() { Frequency = JobRecurrenceFrequency.Minute, Interval = 1, Count = 5 } }); Console.WriteLine(result.RequestId); Console.WriteLine(result.StatusCode); Console.ReadLine();
      
      





このタスクはtaskcoll001タスクコレクションで作成され、特定の本文とリクエストヘッダーを含むPOSTリクエストを送信します。 これはHTTP(S)などのタスクを実行するために必要なので、要求するコンテンツのタイプを指定していることに注意してください。 私は有料のスケジューラプランを使用しているため、毎分繰り返してタスクを作成できます。 このデモでは、タスクを5回の実行に制限しました。



最後に、URIに注意を払うと、 http://postcatcher.inサービスを使用していることに気付くでしょう。 これは無料のサービスで、POSTリクエストをデバッグできます。これはまさに私がやっていることです。 タスクスケジューラの機能を見てみましょう。







ご覧のとおり、スケジューラーはリクエスト本体と、他のデータを含む指定したヘッダーを送信します。 追加のヘッダーには、タスクが実行された場所と、タスクが実行されたタスクのコレクションに関する情報が含まれます。



 { "connection": "close", "content-length": "40", "content-type": "application/x-www-form-urlencoded", "host": "postcatcher.in", "x-forwarded-for": "137.116.241.137", "x-ms-client-request-id": "988c7a64-55e1-41e4-8cf0-ce1eeca240ac", "x-ms-execution-tag": "0726fa245447c91674c75db3f3564d63", "x-ms-scheduler-execution-region": "North Europe", "x-ms-scheduler-expected-execution-time": "2013-11-07T02:39:27", "x-ms-scheduler-jobcollectionid": "jobcoll001", "x-ms-scheduler-jobid": "7ce6971c-5aa1-4701-b6bd-02f63ee82d17", "x-real-ip": "137.116.241.137", "x-request-start": "1383791968800", "x-something": "value123" }
      
      





次に、タスクのタイプをストレージキューに変更します。



 var storageAccount = new CloudStorageAccount(new StorageCredentials("labdrino", ""), true); var queueClient = storageAccount.CreateCloudQueueClient(); var queue = queueClient.GetQueueReference("scheduled-tasks"); queue.CreateIfNotExists(); var perm = new QueuePermissions(); var policy = new SharedAccessQueuePolicy { SharedAccessExpiryTime = DateTime.MaxValue, Permissions = SharedAccessQueuePermissions.Add }; perm.SharedAccessPolicies.Add("jobcoll001policy", policy); queue.SetPermissions(perm); var sas = queue.GetSharedAccessSignature(new SharedAccessQueuePolicy(), "jobcoll001policy"); var schedulerClient = new SchedulerClient(credentials, "sandrino-cs2", "jobcoll001"); var result = schedulerClient.Jobs.Create(new JobCreateParameters() { Action = new JobAction() { Type = JobActionType.StorageQueue, QueueMessage = new JobQueueMessage() { Message = "hello there!", QueueName = "scheduled-tasks", SasToken = sas, StorageAccountName = "labdrino" } }, StartTime = DateTime.UtcNow, Recurrence = new JobRecurrence() { Frequency = JobRecurrenceFrequency.Minute, Interval = 1, Count = 5 } }); Console.WriteLine(result.RequestId); Console.WriteLine(result.StatusCode); Console.ReadLine();
      
      





ご覧のとおり、ストレージキューなどのタスクを作成するには、もう少し作業とコードが必要です。 最初に、キューと、追加する権限を持つポリシーを作成する必要があります。 このポリシーでは、共有アクセス署名を作成する必要があります。これは、後でスケジューラがメッセージをキューに入れるために使用されます。



コード実行の結果は、「hello there!」というメッセージのテキストとともにタスクに関する情報を含むキュー内のメッセージになります。







タスク履歴



タスクが完了したら、間違いなくスケジューラの結果を知りたいでしょう。 これは、渡されたタスク識別子パラメーターでGetHistoryメソッドを使用して実行できます。 タスクを作成すると、タスク識別子が応答として返されます。 Listメソッドを呼び出して、コレクション内のすべてのタスクをスクロールすることもできます。



 var schedulerClient = new SchedulerClient(credentials, "sandrino-cs2", "jobcoll001"); foreach (var job in schedulerClient.Jobs.List(new JobListParameters() { State = JobState.Enabled })) { Console.WriteLine("Job: {0} - Action: {1} - State: {2} - Status: {3}", job.Id, job.Action, job.State, job.Status); foreach (var history in schedulerClient.Jobs.GetHistory(job.Id, new JobGetHistoryParameters())) { Console.WriteLine(" > {0} - {1}: {2}", history.StartTime, history.EndTime, history.Message); } } Console.ReadLine();
      
      





このコードを実行すると、次のような結果が得られます。

ジョブ:34851054-f576-48b8-8c77-73b62b502022-アクション:Microsoft.WindowsAzure.Scheduler.Models.JobAction-状態:Faulted-ステータス:Microsoft.WindowsAzure.Scheduler.Models.JobStatus

> 11/11/2013 2:52:18-11/11/2013 2:52:19:StorageQueueアクション-指定されたキュー: 'scheduled-tasks'が存在しないか、Sasトークンにメッセージを追加する権限がありません指定されたキューへ

> 7/11/2013 2:52:48-7/11/2013 2:52:50:StorageQueue Action-指定されたキュー: 'scheduled-tasks'が存在しないか、Sasトークンにメッセージを追加する権限がありません指定されたキューへ

> 11/11/2013 2:53:19-7/11/2013 2:53:19:StorageQueue Action-指定されたキュー: 'scheduled-tasks'が存在しないか、Sasトークンにメッセージを追加する権限がありません指定されたキューへ

> 11/11/2013 2:53:48-11/11/2013 2:53:50:StorageQueueアクション-指定されたキュー: 'scheduled-tasks'が存在しないか、Sasトークンにメッセージを追加する権限がありません指定されたキューへ

> 11/11/2013 2:54:20-7/11/2013 2:54:20:StorageQueueアクション-指定されたキュー: 'scheduled-tasks'が存在しないか、Sasトークンにメッセージを追加する権限がありません指定されたキューへ

> 11/11/2013 3:05:19-7/11/2013 3:05:19:StorageQueueアクション-指定されたキュー: 'scheduled-tasks'が存在しないか、Sasトークンにメッセージを追加する権限がありません指定されたキューへ

> 11/11/2013 3:05:49 AM-7/11/2013 3:05:49 AM:StorageQueue Action-指定されたキュー: 'scheduled-tasks'が存在しないか、Sasトークンにメッセージを追加する権限がありません指定されたキューへ

> 11/11/2013 3:06:18-11/11/2013 3:06:19:StorageQueueアクション-指定されたキュー: 'scheduled-tasks'が存在しないか、Sasトークンにメッセージを追加する権限がありません指定されたキューへ



ジョブ:4db6da21-af4a-4703-b988-671cbb6d5fd5-アクション:Microsoft.WindowsAzure.Scheduler.Models.JobAction-状態:完了-ステータス:Microsoft.WindowsAzure.Scheduler.Models.JobStatus

> 11/11/2013 2:32:13-11/11/2013 2:32:15:Httpアクション-ホスト 'postcatcher.in'からの応答: 'Created'応答ヘッダー:接続:keep-alive

X応答時間:6ミリ秒

日付:木、2013年11月7日02:32:14 GMT

セットCookie:connect.sid = 8SxhjZXandfZQc158Ng2tiYs.kyW9OSZGymzcIJW1eTJJ2MIACyhSyK6mfHVVqqj2r0E; パス= /; 有効期限=木曜日、2013年11月7日06:32:14 GMT httpOnly

サーバー:nginx

X-Powered-By:エクスプレス

本文:作成済み

> 11/11/2013 2:33:14-11/11/2013 2:33:15:HTTPアクション-ホスト 'postcatcher.in'からの応答: 'Created'応答ヘッダー:接続:keep-alive

X応答時間:18ミリ秒

日付:木、2013年11月7日02:33:15 GMT

Set-Cookie:connect.sid = BJYkjeu3m26wBfr6G2SDgXZl.nhXEo24T3AVHEMYe4xJIm7gjDmhZvj69edIv4bui%2Bzs; パス= /; 有効期限=木曜日、2013年11月7日06:33:15 GMT; httpOnly

サーバー:nginx

X-Powered-By:エクスプレス

本文:作成済み
タスク履歴は、タスクの実行に関する興味深い情報を提供できます。 タスク中に何か問題が発生した場合、履歴は問題の原因を探し始める最初の場所です。



エラーが発生した場合の繰り返し(Retries)



OK、WebサイトにHTTPリクエストを送信するとします。HTTPリクエストは利用できません(バグ、スケジュールされた作業、コードの更新など)。 この場合、数秒後にもう一度タスクを繰り返すことができます。 良いニュースは、タスクの作成中に再試行ポリシーを指定することでこれを実行できることです。



 var schedulerClient = new SchedulerClient(credentials, "sandrino-cs2", "jobcoll001"); var result = schedulerClient.Jobs.Create(new JobCreateParameters() { Action = new JobAction() { Type = JobActionType.Http, Request = ..., RetryPolicy = new RetryPolicy() { RetryCount = 5, RetryInterval = TimeSpan.FromMinutes(1), RetryType = RetryType.Fixed } }, StartTime = DateTime.UtcNow, Recurrence = ... });
      
      





この例では、1分間隔で最大5回の繰り返しを実行するよう指示しています。



エラー処理



何か問題が発生した場合、特定の信号、たとえば、別のキュー(または別のデータセンター)に送信されたメッセージ、または別のURLの呼び出しを受信することができます。 これはすべて、タスクの作成時に特別なエラーセクションのパラメーターを指定することで可能です。 次の例では、StorageQueueストレージキューのタスクを作成しますが、無効なSAS署名を指定します。 これにより、スケジューラーはメッセージをキューに送信するタスクを完了できず、ErrorActionセクションが呼び出されます(エラーメッセージをpostcatcher.inページに送信するコード)。



 var schedulerClient = new SchedulerClient(credentials, "sandrino-cs2", "jobcoll001"); var result = schedulerClient.Jobs.Create(new JobCreateParameters() { Action = new JobAction() { Type = JobActionType.StorageQueue, QueueMessage = new JobQueueMessage() { Message = "hello there!", QueueName = "scheduled-tasks", SasToken = "not working", StorageAccountName = "labdrino" }, ErrorAction = new JobErrorAction() { Type = JobActionType.Http, Request = new JobHttpRequest() { Uri = new Uri("http://postcatcher.in/catchers/527b0b75fe325802000002b6"), Body = "type=somethingiswrong", Headers = new Dictionary() { { "Content-Type", "application/x-www-form-urlencoded" }, { "x-something", "value123" } }, Method = "POST" } } }, StartTime = DateTime.UtcNow, Recurrence = new JobRecurrence() { Frequency = JobRecurrenceFrequency.Minute, Interval = 1, Count = 5 } }); Console.WriteLine(result.RequestId); Console.WriteLine(result.StatusCode); Console.ReadLine();
      
      





その後、ポストキャッチャーでエラーメッセージを確認できます(メッセージヘッダーには、タスクに関連する必要な情報がすべて含まれています)。







タスクの定期的な繰り返し



スケジューラを使用すると、タスクを毎日数回実行できますが、最大10回(Countプロパティ)など、タスクのいくつかのタイプの定期的な繰り返しを構成できます。



 var schedulerClient = new SchedulerClient(credentials, "sandrino-cs2", "jobcoll001"); var result = schedulerClient.Jobs.Create(new JobCreateParameters() { Action = ..., Recurrence = new JobRecurrence() { Frequency = JobRecurrenceFrequency.Day, Interval = 1, Count = 10 } });
      
      





特定の日付の前に毎日タスクを実行するように指定できます。



 var schedulerClient = new SchedulerClient(credentials, "sandrino-cs2", "jobcoll001"); var result = schedulerClient.Jobs.Create(new JobCreateParameters() { Action = ..., Recurrence = new JobRecurrence() { Frequency = JobRecurrenceFrequency.Day, Interval = 1, EndTime = new DateTime(2013, 12, 31) } });
      
      





これに加えて、タスクを定期的に繰り返すためのより複雑なパラメーターを指定できます。 たとえば、メーリングリストの場合、毎週月曜日の午前11:00に完了するタスクを指定できます。



 var schedulerClient = new SchedulerClient(credentials, "sandrino-cs2", "jobcoll001"); var result = schedulerClient.Jobs.Create(new JobCreateParameters() { Action = new JobAction() { Type = JobActionType.Http, Request = new JobHttpRequest() { Body = "customers=Europe-West", Headers = new Dictionary() { { "Content-Type", "application/x-www-form-urlencoded" }, }, Method = "POST", Uri = new Uri("http://postcatcher.in/catchers/527af9acfe325802000001cb") } }, StartTime = DateTime.UtcNow, Recurrence = new JobRecurrence() { // Frequency = JobRecurrenceFrequency.None, Schedule = new JobRecurrenceSchedule() { Days = new List() { JobScheduleDay.Monday }, Hours = new List() { 9 }, Minutes = new List() { 11 } } } });
      
      





ご注意 現在、コントロールライブラリには、[頻度]を[なし](または[スケジュール])に設定できない小さなバグが含まれています。 このため、このタイプの頻度でタスクを作成することはできません。



おわりに



Windows Azureスケジューラには、シンプルなAPI、ストレージキューのサポート、再試行ポリシー、エラー処理があります。 これにより、新しいサービスはスケジュールされたタスクを完了するための優れたツールになります。 さらに、この新しいサービスにより、次のようなシナリオが可能になります。WindowsAzure Webサイトのタスクをスケジュールする(作業ロールを上げる必要なし)。 仕事の役割にデータを送信します。 PHP、Node.jsなどのアプリケーションでスケジューラーを使用します。 Windows Azure SQL Databaseなどの独自のエージェントを構築する



詳細については、次のリンクを参照してください。





お楽しみください!



All Articles