Использование CurrentRoleInstance.Id для запуска задачи только в одном экземпляре - PullRequest
8 голосов
/ 15 марта 2012

В контексте, когда вы развертываете веб-роль в нескольких экземплярах и вам требуется запланировать задачу, которая должна выполняться только одним экземпляром (например, отправить электронное письмо администратору сайта с некоторыми статистическими данными), насколько надежно его использовать RoleEnvironment.CurrentRoleInstance.Id для того, чтобы задача запускалась только на одном экземпляре (например, только если она запускается, если идентификатор заканчивается на IN_0)? Если кто-нибудь когда-либо делал это, мне был бы интересен его отзыв.

Ответы [ 3 ]

10 голосов
/ 15 марта 2012

Я бы не использовал ID экземпляра. Что произойдет, если экземпляр 0 будет перезагружен (что происходит не реже одного раза в месяц)? Теперь ваш планировщик или исполнитель задач не в сети.

Альтернативным решением является использование типа мьютекса, который охватывает экземпляры. То, о чем я думаю, это аренда блобов. На самом деле вы можете получить в аренду блоб для записи (и может быть только один арендатор). Вы можете попытаться получить блоб в аренду перед запуском задачи. Если вы получили его, запустите задание. Если вы этого не сделаете, не запускайте его.

Небольшое отклонение: в потоке (скажем, начатом с вашего Run() метода) попытайтесь получить аренду, а в случае успеха запустите задачу планировщика (возможно, поток или что-то в этом роде). Если вы не можете получить аренду, поспите минуту и ​​попробуйте снова. В конце концов, экземпляр с арендой будет перезагружен (или исчезнет по какой-либо другой причине). Через несколько секунд другой экземпляр получит отмененную аренду и запустит новую задачу планировщика.

Стив Маркс написал сообщение в блоге о параллелизме с использованием аренды. У Тайлера Доерксена также есть хороший пост об аренде.

6 голосов
/ 02 мая 2013

да, при необходимости вы можете использовать InstanceId

 <Startup>
  <Task commandLine="StartUpTasks\WindowService\InstallWindowService.bat"  executionContext="elevated" taskType="background" >
  <Environment>
    <Variable name="InstanceId">
        <RoleInstanceValue xpath="/RoleEnvironment/CurrentInstance/@id"/>
    </Variable>
   </Environment>
  </Task>
 </Startup>

будет иметь следующую форму

<deployment Id>.<Application Name>.<Role Name>_IN_<index>
 Example mostly MyRole_IN_0, MyRole_IN_1

Доступ к переменной окружения в пакетном файле, как этот

 %InstanceId%

Затем можно использовать подстроку или последний индекс _, чтобы получить индекс из InstanceId. если этот экземпляр с индексом 0 будет иметь такой же индекс даже после перезагрузки.

Подробнее http://blogs.msdn.com/b/cclayton/archive/2012/05/17/windows-azure-start-up-tasks-part-2.aspx

http://msdn.microsoft.com/en-us/library/windowsazure/hh404006.aspx

0 голосов
/ 15 марта 2012

Некоторые блоки кода выполнения могут выполняться только один раз, если у вас есть несколько экземпляров, например, путем проверки идентификатора текущего экземпляра роли, в которой вы выполняете.

Вы можете достичь того же результата с другими решениями, но для этого может потребоваться дополнительная работа, например, отделить задачу от вашего экземпляра

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...