2012-03-15 11 views
8

In un contesto in cui si distribuisce un ruolo Web su più istanze e si richiede di pianificare un'attività che deve essere eseguita da una sola istanza (come l'invio di una e-mail al sito admin con alcune statistiche), quanto è affidabile l'uso di RoleEnvironment.CurrentRoleInstance.Id per far sì che l'attività venga eseguita su una sola istanza (come se fosse stata eseguita solo se l'Id termina con IN_0)? Se qualcuno lo avesse mai fatto, sarei interessato al suo feedback.Uso di CurrentRoleInstance.Id per eseguire un'attività in una sola istanza

risposta

10

non userei ID istanza. Cosa succede se l'istanza 0 viene riavviata (cosa che accade almeno una volta al mese)? Ora il tuo programmatore o task-runner è offline.

Una soluzione alternativa consiste nell'utilizzare un tipo di mutex che si estende su istanze. Quello a cui sto pensando è un contratto di blob. È possibile acquistare un contratto di locazione su un BLOB per iscritto (e può esserci un solo lease-holder). È possibile tentare di ottenere un lease blob prima di eseguire un'attività. Se lo ottieni, esegui l'attività. Se non lo fai, non eseguirlo.

Una leggera variazione: in una discussione (diciamo avviata dal metodo Run()), tentare di acquisire un lease e, in caso di esito positivo, avviare un'attività di pianificazione (magari un thread o qualcosa del genere). Se non riesci ad ottenere il contratto di locazione, dormi per un minuto e riprova. Alla fine, l'istanza con il lease verrà riavviata (o scomparirà per qualche altro motivo). Dopo pochi secondi, un'altra istanza acquisirà il contratto di locazione abbandonato e avvierà una nuova attività di pianificazione.

Steve Marx ha scritto un blog post sulla concorrenza utilizzando i leasing. Tyler Doerksen ha anche un good post sui leasing.

+0

Grazie per la risposta, ho già passato attraverso post sul blog di smarx. Tuttavia, non ho completamente compreso il punto sul riavvio dell'istanza. Dopo il riavvio, avrà ancora lo stesso ID di istanza, giusto? In tal caso, sarebbe possibile far fronte alla situazione quando viene riavviato esattamente quando l'attività deve essere eseguita (eseguendola subito dopo il riavvio, ad esempio). – ThomasWeiss

+1

Il mio punto è che si desidera sempre un programma di pianificazione in esecuzione. Se dipendi da un'istanza specifica, hai il tempo di inattività garantito. Inoltre: cosa succede se riduci * in basso *? Non è possibile specificare quale istanza rimuovere.Cosa succede se l'istanza rimossa è quella a cui fai sempre riferimento? –

+0

Vero. Implementerò l'opzione di leasing blob. Grazie. – ThomasWeiss

0

È possibile che un codice di blocco di esecuzione venga eseguito una sola volta se si dispone di più istanze, ad esempio controllando l'ID dell'istanza di ruolo corrente in cui si sta eseguendo.

si potrebbe ottenere lo stesso risultato con altre soluzioni, ma quelli potrebbe richiedere un po 'più di lavoro, come il disaccoppiamento l'attività dalla propria istanza

5

sì, si può utilizzare l'InstanceId se necessario specificatamente

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

sarà di forma seguente

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

accedere alla variabile environmet in file batch come questo

%InstanceId% 

È canna quindi usare la sottostringa o l'ultimo indice di _ per ottenere l'indice da InstanceId. se questa istanza con indice 0 avrà lo stesso indice anche dopo un riavvio.

Maggiori dettagli 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

Problemi correlati