在您在多个实例上部署Web角色并且需要安排应该仅由一个实例完成的任务的上下文中(例如,向具有某些统计信息的站点管理员发送电子邮件),使用它的可靠性如何RoleEnvironment.CurrentRoleInstance.Id
为了使任务仅在一个实例上运行(例如,如果Id以IN_0
完成,则只运行它)?
如果有人这样做过,我会对他的反馈感兴趣。
答案 0 :(得分:10)
我不会使用实例ID。如果实例0重新启动(每月至少发生一次)会发生什么?现在您的调度程序或任务运行程序已脱机。
另一种解决方案是使用一种跨越实例的互斥锁。我想到的是一个blob租约。您实际上可以获取Blob上的租约以进行写入(并且只能有一个租赁持有者)。您可以在运行任务之前尝试获取blob租约。如果你得到它,运行任务。如果不这样做,请不要运行它。
略有变化:在一个线程中(假设从你的Run()
方法开始),尝试获取租约,如果成功,则启动一个调度程序任务(可能是一个线程或其他东西)。如果您无法获得租约,请睡一分钟再试一次。最终,带有租约的实例将重新启动(或者由于某些其他原因它将消失)。几秒钟后,另一个实例将获取废弃的租约并启动新的调度程序任务。
答案 1 :(得分:6)
是的,如果需要,可以使用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
像这样
访问批处理文件中的environmet变量 %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
答案 2 :(得分:0)
如果您有多个实例,可以让一些执行代码块只运行一次,例如检查您正在执行的当前角色实例的ID。
您可以使用其他解决方案获得相同的结果,但这些可能需要更多工作,例如将任务与实例分离