Выполнение запланированных задач в Windows Azure всегда было интересной темой с рядом готовых решений, которые помогали выполнить работу правильно: планировщик мобильных услуг Кварцевый планировщик FluentScheduler , WebBackgrounder , ScheduledEnqueueTimeUtc и т. д. Хотя вы, возможно, успешно использовали эти параметры, на самом деле они не были разработаны специально для ваших приложений Windows Azure, работающих в ролях облачных служб или на веб-сайтах.
Именно по этой причине почти год назад Aditi анонсировала свой новый сервис — масштабируемый планировщик задач, созданный специально для удовлетворения потребностей приложений, работающих на Windows Azure. Планировщик Адити был создан Райан Данн – легенда из команды Windows Azure, несколько месяцев назад служба отметила выполнение своей 500-тысячной задачи и добавила поддержку очередей хранилища Windows Azure. Но недавно Microsoft анонсировала отличную альтернативу Aditi Scheduler — новый сервис Windows Azure 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
Scheduler SDK доступен в виде пакета NuGet (в предварительной версии) и является частью новых библиотек управления.Библиотеки управления Windows Azure , выпущенный некоторое время назад. Сначала вам нужно установить пакет:
PM> Install-Package 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);
Служба планировщика задач работает в облачной службе, поэтому мы начали с создания облачной службы.
На данный момент необходимо учитывать одно: создаваемый облачный сервис должен находиться в регионе, в котором поддерживается служба планировщика 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), так и веб- или рабочие роли (PaaS).Однако теперь мы можем быть уверены, что облачная служба также может содержать «поставщика ресурсов», например планировщик Windows Azure. Чтобы использовать такого поставщика ресурсов в своем облачном сервисе, вам сначала необходимо включить его для своих подписок.
Если вы этого не сделаете, вы столкнетесь со следующей ошибкой:
Необработанное исключение типа «Microsoft.WindowsAzure.CloudException» произошло в Microsoft.WindowsAzure.Management.Scheduler.dll. Дополнительная информация: 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();
Например, этот код позволяет нам узнать планы использования, доступные для сервиса, и регионы, в которых сервис может работать:
Коллекции вакансий
Следующим шагом будет создание «Коллекции заданий», которая представляет собой контейнер для хранения ваших задач и механизм применения к ним различных квот. Кроме того, здесь вам нужно выбрать бесплатные или платные уровни для использования услуги:Коллекция задач содержит группу задач и управляет параметрами, квотами и ограничениями, общими для всех задач в коллекции.Более подробную информацию о квотах, которые можно использовать в обоих планах, можно найти по этой ссылке: http://msdn.microsoft.com/en-us/library/windowsazure/dn479786.aspx .Коллекция задач создается владельцем подписки и группирует задачи в зависимости от потребления или границ приложения.
Сбор заданий ограничен одним регионом.
Он также позволяет устанавливать квоты MaxJobs и MaxRecurrence для метрик потребления всех задач в коллекции.
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 и очереди хранилища.
Давайте сначала посмотрим на поддержку 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();
Эта задача создана в моей коллекции задач «jobcoll001», она отправит запрос POST с определенным телом запроса и заголовками.
Обратите внимание: я указываю тип контента для запроса, поскольку это необходимо для выполнения задач типа HTTP(S).
Поскольку я использую платный планировщик, мне разрешено создавать задачи, повторяющиеся каждую минуту.
Для этой демонстрации я ограничил задачу пятью выполнениями.
Наконец, если вы обратите внимание на 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();
Как видите, создание задачи типа очереди хранилища требует немного больше работы и кода.
Сначала вам нужно будет создать очередь, а также политики для нее с разрешением на добавление.
Для этой политики вам необходимо создать подпись общего доступа, которая позже будет использоваться планировщиком для отправки сообщений в очередь.
Результатом выполнения кода будет сообщение в очереди, содержащее информацию о задаче вместе с текстом «здравствуйте!» сообщение:
История задач
Как только ваши задачи будут выполнены, вам обязательно захочется узнать результаты работы планировщика.Это можно сделать с помощью метода GetHistory и передав ему параметр ID задачи.
После создания задачи идентификатор задачи возвращается в качестве ответа.
Вы также можете просмотреть все задачи в коллекции, вызвав метод 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 — Состояние: Ошибка — Статус: Microsoft.WindowsAzure.Scheduler.Models.JobStatus > 11.07.2013 2:52:18 – 11.07.2013 2:52:19: Действие StorageQueue — предоставленная очередь: «запланированные задачи» не существует или у токена Sas нет разрешения на добавление сообщения в данную очередь > 11.07.2013 2:52:48 – 11.07.2013 2:52:50: Действие StorageQueue — предоставленная очередь: «запланированные задачи» не существует или у токена Sas нет разрешения на добавление сообщения в данную очередь > 11.07.2013 2:53:19 – 11.07.2013 2:53:19: Действие StorageQueue — предоставленная очередь: «запланированные задачи» не существует или у токена Sas нет разрешения на добавление сообщения в данную очередь > 11.07.2013 2:53:48 – 11.07.2013 2:53:50: Действие StorageQueue – предоставленная очередь: «запланированные задачи» не существует или у токена Sas нет разрешения на добавление сообщения в данную очередь > 11.07.2013 2:54:20 – 11.07.2013 2:54:20: Действие StorageQueue – предоставленная очередь: «запланированные задачи» не существует или у токена Sas нет разрешения на добавление сообщения в данную очередь > 11.07.2013 3:05:19 – 11.07.2013 3:05:19: Действие StorageQueue — предоставленная очередь: «запланированные задачи» не существует или у токена Sas нет разрешения на добавление сообщения в данную очередь > 11.07.2013 3:05:49 – 11.07.2013 3:05:49: Действие StorageQueue — предоставленная очередь: «запланированные задачи» не существует или у токена Sas нет разрешения на добавление сообщения в данную очередь > 11.07.2013 3:06:18 – 11.07.2013 3:06:19: Действие StorageQueue — предоставленная очередь: «запланированные задачи» не существует или у токена Sas нет разрешения на добавление сообщения в данную очередь Задание: 4db6da21-af4a-4703-b988-671cbb6d5fd5 — Действие: Microsoft.WindowsAzure.Scheduler.Models.JobAction — Состояние: Завершено — Статус: Microsoft.WindowsAzure.Scheduler.Models.JobStatus > 11.07.2013 2:32:13 – 11.07.2013 2:32:15: Действие Http – Ответ от хоста «postcatcher.in»: «Создано» Заголовки ответа: Соединение: поддержка активности Время отклика X: 6 мс Дата: четверг, 7 ноября 2013 г.История задач может предоставить интересную информацию о выполнении задач., 02:32:14 GMT Set-Cookie: Connect.sid=8SxhjZXandfZQc158Ng2tiYs.kyW9OSZGymzcIJW1eTJJ2MIACyhSyK6mfHVVqqj2r0E; путь =/; истекает = четверг, 7 ноября 2013 г.
, 06:32:14 по Гринвичу; httpOnly Сервер: nginx X-Powered-By: Экспресс Тело: Создано > 11.07.2013 2:33:14 – 11.07.2013 2:33:15: Действие Http – Ответ от хоста postcatcher.in: «Создано» Заголовки ответа: Соединение: поддержка активности Время отклика X: 18 мс Дата: четверг, 7 ноября 2013 г.
, 02:33:15 по Гринвичу Set-Cookie: Connect.sid=BJYkjeu3m26wBfr6G2SDgXZl.nhXEo24T3AVHEMYe4xJIm7gjDmhZvj69edIv4bui%2Bzs; путь =/; истекает = четверг, 7 ноября 2013 г.
, 06:33:15 по Гринвичу; httpOnly Сервер: nginx X-Powered-By: Экспресс Тело: Создано
Если при выполнении задачи что-то пойдет не так, история — это первое место, с которого следует начать поиск источника проблемы.
Повторы в случае ошибок (Retries)
Хорошо, предположим, вы делаете 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 = .
});
В этом примере я указываю максимум пять повторений с минутными интервалами между ними.
Обработка ошибок
В случае, если что-то пойдет не так, вы можете захотеть получить какой-то сигнал, например сообщение, отправленное в другую очередь (или в другой центр обработки данных) или вызов другого 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();
После этого вы сможете увидеть сообщение об ошибке в postcatcher (заголовок сообщения содержит всю необходимую информацию, связанную с вашей задачей):
Периодическое повторение задачи
Планировщик позволяет настроить несколько типов периодического повторения задачи, например запускать задачу каждый день, но максимум 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, поддержку очередей хранилища, политик повторных попыток и обработки ошибок.Это делает новый сервис отличным инструментом для своевременного выполнения ваших задач.
Кроме того, новый сервис открывает множество сценариев: планирование задач для вашего веб-сайта Windows Azure (без необходимости повышения рабочих ролей); отправка данных на вашу рабочую роль; использование планировщика в своих приложениях на PHP, Node.js и т.д.; создание собственного агента для базы данных SQL Windows Azure и т. д. Более подробную информацию можно найти по следующим ссылкам:
- Домашняя страница службы планировщика Windows Azure: http://www.windowsazure.com/ru-ru/services/scheduler/ ;
- Информация о ценах: http://www.windowsazure.com/ru-ru/pricing/details/scheduler/ (не забудьте прочитать FAQ);
- Информация о квотах http://msdn.microsoft.com/en-us/library/windowsazure/dn479786.aspx
- Информация об использовании библиотек управления Windows Azure http://habrahabr.ru/company/microsoft/blog/201566/
NET #Библиотеки управления Windows Azure #облачные службы #планировщик задач #разработка веб-сайтов #.
NET #Microsoft Azure
-
Одномерный Генератор Случайных Чисел
19 Oct, 24 -
Что Нового В Flash Player 10.1
19 Oct, 24 -
Гуадек-2012: Как Это Было
19 Oct, 24