2015-09-18 6 views
0

Я работаю с очередью служебной шины Azure (или потенциально, если это необходимо), и хотел бы знать, как использовать Web-задание в очереди.Azure Webjobs and Queues

Когда сообщение приходит в очередь, оно представляет собой процесс, который будет запускаться в веб-задании (или запускаться из веб-сайта). Этот процесс может быть быстрым, 30 секунд или может быть медленным, 1 час и т. Д.

Могу ли я использовать для этого один веб-ресурс и как-то сказать, что он должен работать не более чем из 10 таких процессов за раз ?

ответ

1

Да, вы можете использовать WebJob. Я создал простой WebJob с очередью хранения, чтобы просто определить, как это можно сделать. В приведенном ниже рабочем процессе будет выполняться всего десять процессов за раз и сохранить все остальные запросы в памяти ConcurrentQueue. Вы должны реализовать логику его и из очереди потреблять его

public class Functions 
{ 
    public delegate void CompletedProcessHandler(object sender, CompletedProcessHandlerArgs args); 

    static readonly Dictionary<int, CustomProcess> _dictionary = 
     new Dictionary<int, CustomProcess>(); 
    static readonly ConcurrentQueue<ProcessEntity> _remaining = 
     new ConcurrentQueue<ProcessEntity>(); 

    // This function will get triggered/executed when a new message is written 
    // on an Azure Queue called queue. 
    public static void ProcessQueueMessage([QueueTrigger("testqueue")] ProcessEntity msg, 
     TextWriter log) 
    { 
     if (_dictionary.Count <= 10) 
     { 
      var newProcess = new CustomProcess((_dictionary.Last().Key) + 1, 
       msg.Duration); 
     } 
     else 
     { 
      _remaining.Enqueue(msg); 
     } 

    } 

    public static void CompletedProcess(object sender, CompletedProcessHandlerArgs args) 
    { 
     _dictionary[Int32.Parse(args.ProcessID)].Dispose(); 
     _dictionary.Remove(Int32.Parse(args.ProcessID)); 
    } 
} 

public class CustomProcess : IDisposable 
{ 
    public event Functions.CompletedProcessHandler OnProcessCompleted; 
    private CancellationTokenSource _token; 
    private string _id; 
    private Timer _timer; 
    public CustomProcess(int i, int duration) 
    { 
     _timer = new Timer { Enabled = true, Interval = duration * 1000 }; 
     _timer.Elapsed += Timer_Elapsed; 
     _id = i.ToString(); 
     _token = new CancellationTokenSource(); 

     Task.Factory.StartNew(() => WriteMessages()); 
     _timer.Start(); 

     OnProcessCompleted += Functions.CompletedProcess; 

    } 

    private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     _token.Cancel(); 
     OnProcessCompleted?.Invoke(this, new CompletedProcessHandlerArgs(_id)); 
    } 

    private void WriteMessages() 
    { 
     while (!_token.Token.IsCancellationRequested) 
     { 
      Console.WriteLine("Test Message from process " + _id); 
     } 
    } 

    public void Dispose() 
    { 
     _token.Dispose(); 
     _timer.Dispose(); 
    } 
} 


public class CompletedProcessHandlerArgs : EventArgs 
{ 
    public string ProcessID { get; set; } 

    public CompletedProcessHandlerArgs(string ID) 
    { 
     ProcessID = ID; 
    } 
} 


public class ProcessEntity 
{ 
    public int Duration { get; set; } 
} 

В app.config веб работы необходимо предоставить два настройки приложения

<add name="AzureWebJobsDashboard" 
    connectionString="DefaultEndpointsProtocol=https;AccountName=[AccountName];AccountKey=[AccountKey]" /> 
<add name="AzureWebJobsStorage" 
    connectionString="DefaultEndpointsProtocol=https;AccountName=[AccountName];AccountKey=[AccountKey]" /> 

файл программы по умолчанию один из шаблона Visual Studio

public class Program 
{ 
    // Please set the following connection strings in app.config for this WebJob to run: 
    // AzureWebJobsDashboard and AzureWebJobsStorage 
    static void Main() 
    { 
     var host = new JobHost(); 
     // The following code ensures that the WebJob will be running continuously 
     host.RunAndBlock(); 
    } 
} 

WebJob сохранит сообщение об ошибке в тот момент, когда он появится. Поскольку вы хотите, чтобы только 10 выполнялось одновременно, вам нужно будет выложить сообщение в память и дождаться завершения процесса до того, как вы запустите новый.

Поскольку @Rick упомянул, вы можете установить для свойства is_Singleton значение true в settings.job файл веб-сайта

+0

Итак, вы говорите, что вы запустите фоновый процесс для 10 предметов. И задача будет выполняться в течение нескольких секунд, записывая материал на консоль, прежде чем она будет отменена? Спасибо, что выглядит хорошо. – peter

+0

Да, это идея. Вам также необходимо позаботиться об удалении элементов из ConcurrentQueue. Также этот дизайн хорош, если webjob отмечен как singleton – Sandesh

+0

Что произойдет, если все это исчезнет или произойдет сбой? Тогда разве это не удаляет ConcurrentQueue и данные теряются? – peter

0

Да, вы можете запустить веб-работу с очередью или темой служебной шины Azure. Хорошим примером того, как вы собираетесь работать, будет шаблон сценария быстрого запуска Service Bus в Visual Studio.

enter image description here

В частности, вы хотите посмотреть на ServiceBusTrigger приписывать, что веб-Jobs SDK предоставляет.

Что касается масштабируемости веб-работы, это будет масштабироваться в соответствии с вашими примерами веб-приложений. Итак, если вы сказали, что 5 экземпляров вашего веб-приложения с всегда включены в, тогда у вас будет 5 экземпляров вашей веб-работы. В качестве дополнительного комментария к этому, если вы хотите получить только один экземпляр веб-задания в среде из 5 экземпляров веб-приложений, вы можете установить свойство is_singleton в true в файле settings.job.