Microsoft — мировой лидер в области ПО и ИТ-услуг
381,25
рейтинг
31 марта 2014 в 08:51

Разработка → WebJob в Microsoft Azure

Не так давно в Microsoft Azure появилась новая фича — WebJob, правда, пока в стадии alpha 2.
Основная идея WebJob — дать возможность запускать в Azure задачи по расписанию. Плюс, для .NET кода предоставляется простой API для event driven обработки.

Решения до WebJob


Если было действие, которое нужно запускать раз в день то раньше это решалось несколько странно для Cloud Platform:

Вариант 1:

Создать виртуалку, и в Windows Scheduler поставить новую задачу. Этот вариант отлично работает, но в рамках виртуальной машины. Если нужно, например, логи сайта с WebSite Role сжимать и отправлять куда-нибудь, то виртуалка абсолютно бесполезна. Есть конечно и плюс — нет привязки к Azure.

Вариант 2:

Планировщик Windows Azure Scheduler. Пример по русски . Проблема в том, что для его использования надо написать код, который, в общем-то, лично мне кажется не обязательным: все должно быть проще.
Таким образом, можно запустить .NET код, но что делать, если логика написана на батниках или на powershell?
Ну и самое важное: сервис предполагается использовать для:
  • Invoking a Web Service over HTTP/s
  • Post a message to a Windows Azure Storage Queue

Такой набор мне кажется очень ограниченным.

Вариант 3:

Worker Role, которая в активном режиме будет жить и по заложенному вами алгоритму, выполнять действия. Есть один момент: такой подход совсем не Event Driven. Так, можно запустить .NET код, но что делать, если код опять же на батниках или на powershell? Ну и еще один момент: т.к. Worker Role — это инстанс, за который надо платить, а не отдельно стоящий .exe файл к вашему WebSite Role.

Что же может предложить WebJob, чего не предлагают все выше перечисленные варианты?



Запуск exe, bat, sh, ps файлов по расписанию или прямо из web-интерфейса.
Расписание можно установить достаточно сложное


Для .NET WebJob дополнительно дает API, связывающий ваш код, с внешними источниками событий (очередями, таблицами, блобами). Это Api является не обязательным, но дает плюшку в виде — окна во внешний мир, позволяющее реагировать на события.

Сам список job будет доступен на вкладке сайта:



Предварительные настройки:

Запустить все это можно и локально, без деплоя на Azure, но давайте это сделаем по-честному — загрузим в Azure. Для этого нам понадобится:
  • Создать аккаунт в Azure. Я взял Trial на 30 дней;
  • Создать Web Site;
  • Создать Storage.


Типы Web Job


WebJob можно разделить на 3 типа:
  • On Demand Task — по требованию (ручной запуск: после загрузки появляется кнопка «Запустить»);
  • Continuously Running Task — постоянно работающие задачи (после загрузки zip архива стартует автоматически и живет вечно, а .NET код реагирует на появление новых файлов в очереди);
  • Scheduled Task — запускаемые по расписанию

Для варианта Scheduled придется сделать дополнительный шаг, а именно согласиться на использование фичи.


Я этого делать не буду, об этом более подробно можно прочесть тут.

Загрузим простой powershell скрипт, запакованый в обычный zip архив.


Загрузили, запустили. Теперь хочется понять, что этот скрипт сделал-то.


Ну, тут уже играет свою роль особенность запуска powershell. Скрипт хоть и упал внутри, но сам powershell.exe завершился вполне корректно.



Мониторинг


Типичные решения на Windows, как то: Windows service или задача в Windows scheduler имеют одну общую проблему — никогда не знаешь работают они или нет, пока не глянешь на список процессов. Не раз натыкался на ситуацию, когда сервис умирал, но т.к. его через WebUi не видно, то узнаешь о его падении по косвенным признакам (как всегда — логи, крики пользователей, отвалился функционал в UI). Написание WatchDog — это конечно решение, но надо писать код и проверять, что Watchdog сам по себе работает.

Еще одной проблемой является- а запускался ли он по расписанию? Это можно понять из логов, но их же читать надо.

WebJob, как и все остальные сервисы Azure, предоставляет какой-никакой, но интерфейс просмотра состояния вашего Webjob и статуса запусков.


На этом базовая фича- запуск исполняемого файла по расписанию закончена.

Привязки через Queue (очереди), Blobs (блобы)


Рассмотрим самый тривиальный пример:

Через nuget установлены 2 пакета:
  • Install-Package Microsoft.WindowsAzure.Jobs -Pre;
  • Install-Package Microsoft.WindowsAzure.Jobs.Host -Pre.

Они за собой еще потянули Newtonsoft.Json и Microsoft.WindowsAzure.ConfigurationManager, но это мелочи.
Перед нами консольное приложение, ничего специфичного в нем нет.


В методе main создаем объект JobHost и вызываем метод RunAndBlock().
Больше никакой логики при запуске можно не создавать. Как мы видим, из Main никаких других вызовов, кроме RunAndBlock нет.
При загрузке в Azure система сама распознает методы, у которых входные параметры размечены атрибутами типа *Input (например, QueueInput) и вызывает эти методы. Т.е. окно во внешний мир за нас уже прорубили. Наша задача — отработать входное сообщение.

Как и когда Azure понимает, что нужно вызвать метод?

Azure дергает метод, когда в соответствующую очередь/таблицу/блоб добавляется новое значение. Получается такой Event Driven стиль. При этом нам не надо заморачиваться с API чтением объектов из blob, queue, table: за нас инфраструктура WebJob сделает это сама.

Я специально сделал этот пример с одной неточностью, чтобы показать что мы увидим в логах. Выходная строка должна быть out string output – такова специфика.
Вот так эта ошибка будет видна.


Теперь исправим код:



Чтобы показать, как он работает:
  • я установил Azure Storage Explorer.
  • Создал 2 очереди: myqueye и myqueuecopy.

Добавим новое сообщение.


И на выходе получим сообщение уже в другой очереди:


Вот так, будет выглядеть результат корректной отработки



Binding (привязка) параметров


Хорошая статья про Binding (привязка) параметров, где подробно рассказано об Input параметрах.

Из интересного:

1. Если у метода есть 2 *Input аргумента, то он будет вызван по добавлению нового объекта в первую очередь/блоб/таблицу, а при добавлении во вторую — нет.

2. Можно использовать не только BlobInput и BlobOutput атрибуты, но и механизм, схожий с routing в mvc/webAPI.
В данном случае мы получаем название blob, и относительно этого уже можем строить какую-то логику.



3. Не только Stream или строка.
SDK позволяет десериализовать из входного потока более сложный объект, чем просто stream.



Дополнительные ссылки




Ссылка на примеры описанные выше на github. Строки подключения к Storage не действительные, они оставлены как образец, чтобы понять как они выглядят.

P.S. Для тех, кто читает Хансельмана или блог команды asp.net. Я, по сути, повторил то, что сделали они, но добавил, чем это решение отличается от того, что было ранее.

Если Вы хотите помочь улучшить статью- предлогайте ваши правки через github
Автор: @SychevIgor
Microsoft
рейтинг 381,25
Microsoft — мировой лидер в области ПО и ИТ-услуг

Комментарии (0)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка