Azure Webjobs和队列

时间:2015-09-18 05:07:29

标签: azure azureservicebus azure-webjobs

我正在使用Azure服务总线队列(或者如果需要,可能是某个主题),并且想知道如何将Web作业与队列一起使用。

当消息进入队列时,它表示将在Web作业中运行的进程(或从webjob启动)。这个过程可能很快,30秒,或者可能很慢,1小时等。

我是否可以为此使用单个Web作业,并以某种方式说它一次应该运行不超过10个这样的进程?

2 个答案:

答案 0 :(得分: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所提到的,你可以在web作业的settings.job文件中将is_Singleton属性设置为true

答案 1 :(得分:0)

是的,您可以使用Azure Service Bus Queue或Topic触发Web作业。一个很好的例子就是Visual Studio中的Service Bus快速启动项目模板。

enter image description here

特别是,您希望查看Web Jobs SDK提供的ServiceBusTrigger属性。

对于Web作业的可伸缩性,这将根据您的Web应用程序实例进行扩展。因此,如果您说启用了始终开启的5个Web应用实例,那么您将拥有5个Web作业实例。作为对此的补充评论,如果您只想在5个Web应用程序实例的环境中创建一个Web作业实例,则可以在settings.job文件中将 is_singleton 属性设置为true。 / p>