2012-03-15 5 views
8

En un contexto en el que está implementando una función web en varias instancias y necesita programar una tarea que solo debe realizar una instancia (como enviar un correo electrónico al sitio admin con algunas estadísticas), ¿qué tan confiable es usar RoleEnvironment.CurrentRoleInstance.Id para hacer que la tarea se ejecute solo en una instancia (como si solo se ejecutara si el Id termina con IN_0)? Si alguien alguna vez ha hecho esto, me interesaría su opinión.Uso de CurrentRoleInstance.Id para ejecutar una tarea en una sola instancia

Respuesta

10

yo no usaría ID de instancia. ¿Qué sucede si se reinicia la instancia 0 (que ocurre al menos una vez al mes)? Ahora su planificador o su tarea-corredor está fuera de línea.

Una solución alternativa es utilizar un tipo de exclusión mutua que abarca instancias. El que estoy pensando es un arrendamiento de blobs. En realidad, puede adquirir un contrato de arrendamiento en un blob por escrito (y solo puede haber un titular de arrendamiento). Podría intentar obtener un arrendamiento blob antes de ejecutar una tarea. Si lo obtiene, ejecute la tarea. Si no lo haces, no lo ejecutes.

Una pequeña variación: en un hilo (digamos empezado desde su método Run()), intente adquirir un contrato de arrendamiento y, si tiene éxito, inicie una tarea de programador (tal vez un hilo o algo así). Si no puede adquirir el contrato, duerma un minuto y vuelva a intentarlo. Eventualmente, la instancia con el arrendamiento se reiniciará (o desaparecerá por algún otro motivo). Después de unos segundos, otra instancia adquirirá el arrendamiento abandonado y comenzará una nueva tarea del programador.

Steve Marx escribió un blog post sobre la concurrencia mediante arrendamientos. Tyler Doerksen también tiene un good post sobre arrendamientos.

+0

gracias por la respuesta, ya pasaron por el blog de Smarx. Aún así, no entiendo completamente su punto sobre la instancia que se reinicia. Después del reinicio, aún tendrá la misma ID de instancia, ¿verdad? Si es así, sería posible hacer frente a la situación cuando se reinicia exactamente cuando se debe ejecutar la tarea (ejecutándola justo después del reinicio, por ejemplo). – ThomasWeiss

+1

Mi punto es que siempre quieres que se ejecute un planificador. Si depende de una instancia específica, se garantiza que tendrá tiempo de inactividad. Además, ¿qué sucede si escala * hacia abajo *? No puede especificar qué instancia eliminar.¿Qué sucede si la instancia eliminada es a la que se refiere todo el tiempo? –

+0

Es cierto. Implementaré esa opción de arrendamiento blob. Gracias. – ThomasWeiss

0

Es posible hacer que un bloque de código de ejecución solo se ejecute una vez si tiene varias instancias, por ejemplo, verificando el ID de la instancia de rol actual en la que está ejecutando.

que podría lograr el mismo resultado con otras soluciones, pero los que pueden requerir más trabajo, al igual que la tarea de desacoplamiento de la instancia

5

sí se puede utilizar el InstanceId si es necesario específicamente dirigidos

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

será de la forma siguiente

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

acceder a la variable environmet en archivo por lotes como éste

%InstanceId% 

Usted Entonces, use subcadena o el último índice de _ para obtener el índice de InstanceId. si esta instancia que tiene el índice 0 tendrá el mismo índice incluso después de reiniciar.

Más detalles 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

Cuestiones relacionadas