2012-06-07 33 views
6

Es posible ejecutar un hilo desde el método WebRole.cs OnStart() de tal forma que podamos acceder a él a través de la página aspx para realizar un trabajo de fondo. Sé que la forma correcta de hacerlo sería utilizar un Rol de trabajador, pero deseo mantener los costos de funcionamiento lo más bajo posible.Subtítulo de fondo en Azure Web Role

La idea sería crear un hilo que estaría siempre ejecutándose y esperando un trabajo, por ejemplo, si quiero hacer una operación de bloqueo como enviar un correo electrónico, usaría el hilo del método SendEmail, ¿es posible? ¿que hacer? Si es así, ¿puede darme algunos ejemplos que puedan orientarme en la dirección correcta?

+0

¿Cómo eso reduciría los costos de funcionamiento? ¿Qué diferencia hay entre el servicio de simultaneidad único de una sola instancia? – Paparazzi

+3

@Blam: la ejecución de tareas en segundo plano en un rol web permite la combinación de operaciones en un solo conjunto de instancias de máquina virtual. Esto está en contraste con colocar operaciones de fondo en un conjunto separado de instancias de rol. Combinar en una función ahorraría costos, ya que cada función debe tener al menos una instancia ejecutándose. Para sitios de bajo volumen, esta es una gran arquitectura que ahorra costos.Si existe el riesgo de que las tareas en segundo plano mueran de hambre en el sitio web, o si es necesario escalar las tareas de fondo y de fondo por separado (o tienen diferentes necesidades de tamaño de VM), vale la pena considerar el cambio a un rol separado. –

+0

@DavidMakogon Gracias. No sabía que un Rol de Trabajador requería una instancia separada. Y no intenté responder la pregunta. +1 Aprendí mucho de esta pregunta. – Paparazzi

Respuesta

10

Me suggets una solución que es diferente de solución de León y de David: solución

  • de David está bien pero no es elástico. ¿Qué parte de la instancia/proceso se desconecta mientras se procesa la tarea?
  • La solución de Leon se aplica principalmente a trabajos programados, pero enviar un correo electrónico no siempre es algo programado (quizás quiera enviar un correo electrónico cuando alguien se registre en su aplicación).

Otra opción que usted debe tener en cuenta es el uso de Azure colas de almacenamiento de Windows (que son muy baratos) en este escenario:

  • Su aplicación web: envía mensajes a la cola (como 'enviar un correo electrónico a [email protected] ')
  • WebRole.cs: generar un nuevo hilo al iniciar la instancia y hacer que escuche los mensajes de esa cola. Cuando llega un mensaje, trátelo. Si tiene éxito, elimine el mensaje de la cola.

Esta solución tiene muchas ventajas. WebRole.cs se ejecuta en un proceso diferente al de su aplicación web, por lo que no afecta a los hilos de solicitud. Y además de eso, si el envío del correo falla por alguna razón, el mensaje permanecerá en la cola y se procesará la próxima vez. Esto asegurará que no perderá ninguna tarea para ejecutar si la aplicación o el proceso falla.

Aquí hay un ejemplo para comenzar. Tenga en cuenta que necesitará mejorar este código si quiere que esté listo para producción (política de reintento, manejo de excepciones, sondeo de rechazo, ...):

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); 
       } 
      } 
     } 
    } 
} 
+0

Parece una mejor solución para el tipo de trabajo que estoy dispuesto a realizar, de todos modos estaba planeando tener colas para "hablar" con una aplicación local, así que no será tan caro ... ¿Puede detallar más cómo para "generar un nuevo hilo al iniciar la instancia y hacer que escuche los mensajes de esa cola"? ** sería genial si pudiera darme un ejemplo o señalarme una muestra que explique la parte de enhebrado involucrada en iniciar un hilo de escucha en WebRole.cs **. Gracias – ToinoBiclas

+0

de acuerdo: las colas son muy resistentes. Mi intención era señalar la viabilidad de crear hilos (lo cual no siempre es obvio). –

+0

@Sandrino Avísame si esto está en línea con tu solución ... crea un hilo en WebRole.OnStart() 'new Thread (new ThreadStart (ClassListeningToQueue.Method0)' luego dentro de Method0 escribe un bucle infinito o un bucle con una condición eso solo cambia a través de WebRole.OnStop() 'while (true) {try {CloudQueueMessage msg = queue.GetMessage(); if (msg! = null) {' finnaly realiza la tarea de acuerdo con los valores dentro del mensaje, por ejemplo, podría tiene un campo que indica qué método llamar y los parámetros también. ¿Es seguro llamar a otros hilos dentro del hilo principal? – ToinoBiclas

1

me encontré con esto cuando yo estaba buscando "tareas programadas azules": http://www.ronaldwidha.net/2011/02/23/cron-job-on-azure-using-scheduled-task-on-a-web-role-to-replace-azure-worker-role-for-background-job/

parece exactamente lo que estás buscando.

+0

El ejemplo que ha indicado es para ejecutar trabajos programados, al igual que crontabs en Linux. Lo que estoy dispuesto a hacer es tener un hilo esperando ser señalado. – ToinoBiclas

+0

Es solo para señalar que definitivamente es posible hacer este tipo de cosas. Supongo que puedes encontrar una solución con un poco de creatividad. –

2

Absolutamente puede crear un hilo (o muchos de ellos). Un rol web es básicamente Windows 2008 Server. No necesita un Rol de trabajador por separado solo para configurar una tarea en segundo plano. Por supuesto, puede tener un rol de trabajador por separado, lo que le permitiría escalar esas instancias independientemente de sus instancias de rol Web. Aquí es donde deberá equilibrar el rendimiento/escalabilidad con el costo.

+0

¿Me puede dar algunos detalles sobre cómo hacer esto? ¿Cómo puedo acceder a la variable de subproceso desde una de las páginas web de aspx si se ha declarado en WebRole: RoleEntryPoint? – ToinoBiclas

+2

Si necesita interactuar con hilos de sus páginas aspx, ¿por qué no iniciar los hilos desde global.asax? RoleEntryPoint se ejecutará en un dominio de aplicación independiente, por lo que no tendrá interacción entre la aplicación y el hilo. –

+0

Honestamente, nunca pensé en eso. Trataré de hacer algunas pruebas con un Thread Pool declarado en global.asax. – ToinoBiclas

Cuestiones relacionadas