avrei suggets una soluzione che è diversa dalla soluzione Leon e David: soluzione
- di David è male, ma non è resiliente. Che cosa l'istanza/processo va offline durante l'elaborazione dell'attività?
- La soluzione di Leon si applica principalmente ai lavori programmati, ma l'invio di una e-mail non è sempre qualcosa che è in programma (forse si desidera inviare una e-mail quando qualcuno si registra nella tua app).
Un'altra opzione che si dovrebbe guardare sta utilizzando Azure code di Windows (sono molto a buon mercato) in questo scenario:
- L'applicazione web: invia messaggi alla coda (come 'inviare una mail a [email protected] ')
- WebRole.cs: genera un nuovo thread all'avvio dell'istanza e fa in modo che ascolti i messaggi da quella coda. Ogni volta che arriva un messaggio, elaboralo. In caso di successo, rimuovere il messaggio dalla coda.
Questa soluzione ha molti vantaggi. WebRole.cs viene eseguito in un processo diverso rispetto all'applicazione Web, quindi non c'è alcun impatto sui thread di richiesta. Inoltre, se l'invio della posta non riesce per qualsiasi motivo, il messaggio rimarrà in coda e verrà elaborato la volta successiva. Ciò assicurerà che non perderai nessuna attività da eseguire se l'applicazione o il processo si bloccano.
Ecco un esempio per iniziare. Si noti che è necessario migliorare questo codice se si vuole che sia pronto per la produzione (la politica, la gestione delle eccezioni, backoff polling, ... ritentare):
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Diagnostics;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.StorageClient;
using System.Threading.Tasks;
namespace MvcWebRole1
{
public class WebRole : RoleEntryPoint
{
public override bool OnStart()
{
Task.Factory.StartNew(InitializeQueueListener);
return base.OnStart();
}
private void InitializeQueueListener()
{
Microsoft.WindowsAzure.CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>
{
configSetter(Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.GetConfigurationSettingValue(configName));
});
var storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
var queueStorage = storageAccount.CreateCloudQueueClient();
var queue = queueStorage.GetQueueReference("myqueue");
queue.CreateIfNotExist();
while (true)
{
CloudQueueMessage msg = queue.GetMessage();
if (msg != null)
{
// DO SOMETHING HERE
queue.DeleteMessage(msg);
}
else
{
System.Threading.Thread.Sleep(1000);
}
}
}
}
}
fonte
2012-06-07 13:32:11
Come vorrei che ridurre i costi di gestione? In che modo ciò che desideri è diverso dal singolo servizio di concorrenza a istanza singola? – Paparazzi
@Blam: l'esecuzione di attività in background in un ruolo Web consente di unire le operazioni in un unico set di istanze VM. Ciò è in contrasto con l'inserimento delle operazioni in background in un set separato di istanze di ruolo. La combinazione in un ruolo consente di risparmiare costi, poiché ogni ruolo deve avere almeno un'istanza in esecuzione. Per i siti con volumi ridotti, questa è una grande architettura a basso costo.Se c'è il rischio che i task in background facciano la fame nel sito Web, o se sia necessario scalare separatamente le attività front-end e in background (o avere esigenze di dimensioni diverse della macchina virtuale), vale la pena considerare il passaggio a un ruolo separato. –
@DavidMakogon Grazie Non sapevo che un ruolo operaio richiedesse un'istanza separata. E non ho provato a rispondere alla domanda. +1 Ho imparato molto da questa domanda. – Paparazzi