我有一个功能,它是订阅主题的服务总线触发器,它聚合特定实体(1:M)的数据,并最终调用DocumentDb存储过程来实现实体。因此,对于每条消息,请说出我正在操作的60个实体(upserting)。
我是垃圾邮件(我猜)CosmosDb(RU是400,所以不是很大,它只是一个测试Db)并开始接收Request rate is too large
例外,所以我研究了如何最好地处理它,并注意到某个地方的代码示例利用了RetryAfter
上的DocumentClientException
属性,并想知道如何计算此属性?
docs并不完全正确,但就生产级别事件而言,我希望能够提供这类信息。
每次尝试都是某种斐波那契序列还是?此外,它如何跟踪已经进行了多少次尝试? (或者是吗?)
答案 0 :(得分:0)
时间跨度背后的逻辑解释为here。
使用绑定获取DocumentClient
时,它使用default constructor。
客户端已default对Request rate is too large
个错误重试一次(默认为9次)。
如果您想要更精细或自定义控制,您可以自行管理DocumentClient
实例而无需绑定,并设置MaxRetryAttemptsOnThrottledRequests或MaxRetryWaitTimeInSeconds。
如果要创建自己的DocumentClient
,我建议将其设为static。
无论哪种方式,如果您尝试/抓住DocumentClientException
并检查StatusCode
429,您将能够捕捉超出MaxRetryAttemptsOnThrottledRequests
的方案。
例如:
#r "Microsoft.Azure.Documents.Client"
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using System.Net;
using System.Configuration;
private static string endpointUrl = ConfigurationManager.AppSettings["cosmosDBAccountEndpoint"];
private static string authorizationKey = ConfigurationManager.AppSettings["cosmosDBAccountKey"];
private static DocumentClient client = new DocumentClient(new Uri(endpointUrl), authorizationKey, new ConnectionPolicy() {
RetryOptions = new RetryOptions()
{
MaxRetryAttemptsOnThrottledRequests = 10,
MaxRetryWaitTimeInSeconds = 20
}
});
});
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
string id = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "id", true) == 0)
.Value;
if (string.IsNullOrEmpty(id)){
return req.CreateResponse(HttpStatusCode.BadRequest);
}
Uri documentUri = UriFactory.CreateDocumentUri("name of database","name of collection",id);
try {
Document doc = await client.ReadDocumentAsync(documentUri);
}
catch(DocumentClientException ex){
int statusCode = (int)ex.StatusCode;
if (statusCode == 429) {
// Request rate errors went over the MaxRetryAttemptsOnThrottledRequests
// Do something you want here
}
throw;
}
if (doc == null){
return req.CreateResponse(HttpStatusCode.NotFound);
}
return req.CreateResponse(HttpStatusCode.OK, doc);
}