如何通过webjob

时间:2017-11-09 07:22:39

标签: c# multithreading azure azure-webjobs azure-queues

我有一个管道,其中外部系统每小时排入大量消息,可能大小为1.000。如果执行了特定操作,则可能是50.000。我有一个webjob,它使用这个队列,并将它们提供给SQL服务器。

Webjob将同时使用8条消息,并且一旦收到响应,就会消耗下一条消息。我的问题是,这有效地占用了SQL服务器拥有的所有资源。我只对队列最终被清空感兴趣,但是没有时间限制(除了它应该能够在下一批进入之前完成)。

有可能选择NextVisibilityTime - 但这种做法根本没有做任何事情(除非我在插入时间上做了一些聪明的伎俩,但这看起来非常h​​acky)。我尝试实现Polly重试逻辑,如下所示:

 var _retryPolicy = Policy
                .HandleResult<HttpResponseMessage>(r => !r.IsSuccessStatusCode)
                .WaitAndRetryAsync(
                    4,
                    retryAttempt => TimeSpan.FromSeconds(Math.Pow(1, retryAttempt)),
                    (ex, timespan, context) =>
                    {
                        Logger.Log("Queue retry increased");
                    });

基本思想是,如果服务器无法跟上,它将返回错误代码。如果发生这种情况,我会服用一种“避孕药”。并且在重试之前稍等一下(在上面的示例中,重试将是即时的,1s,2s,4s,8s,16s)。然而,这似乎很容易打破30秒消息的最大执行时间。如果发生这种情况,Polly将无法达到重新抛出的程度,因此消息不会被添加到毒药队列中。

实际上,我正在寻找一种方法来智能地分散我对消息的消费。如果它是一个函数我可以改变我可以拥有多少并发读取,但将其设置为仅消耗1或2个消息似乎也是一种天真的方法。

任何想法都表示赞赏。

编辑:处理邮件的代码:

var response = await client.PostAsync(endpoint, new StringContent(payload, Encoding.UTF8, "application/json"));

基本上,端点是对SQL服务器顶部的API的HTTP post请求,它将消息的有效负载(JSON数据结构)解析为POCO并将其插入数据库。这可能会有所变化,但它是在.NET Core 1.0中制作的,并且某些库之间存在依赖引用问题。其目的是不必通过HTTP请求。

如果响应不是200,则polly重试逻辑将启动。

0 个答案:

没有答案