作者:借钱买黄瓜 | 来源:互联网 | 2023-05-16 12:10
如何解决《例外:从DocumentDB查询时出现Microsoft.Azure.Documents.RequestRateTooLargeException》经验,为你挑选了2个好方法。
y查询是这样的
this.ProcessRequestSync(() => this.Client.CreateDocumentQuery(this.DocumentDBCollectionLink).Where(d => d.name.Equals(name) && d.code.Equals(code) && d.Type.Equals(this.documentType) && d.CreatedBy.Equals(myName).ToList());
public dynamic ProcessRequestSync(Func getRequest)
{
var delay = TimeSpan.Zero;
var minDelayTime = new TimeSpan(0, 0, 1);
for (;;)
{
try
{
Thread.Sleep(delay);
return getRequest();
}
catch (DocumentClientException documentClientException)
{
var statusCode = (int)documentClientException.StatusCode;
if (statusCode == 429 || statusCode == 503)
{
string errorMessage = string.Format("failed at DocumentDB with {0} status and {1} retry time", statusCode, documentClientException.RetryAfter);
this.Logger.Log(errorMessage );
// Back off if the request rate is too large or the service is temporarily unavailable
delay = TimeSpan.Compare(documentClientException.RetryAfter, minDelayTime) >= 0 ? documentClientException.RetryAfter: minDelayTime;
}
else
{
throw;
}
}
}
}
这是requestRateTooLarge异常引发时重试逻辑的方法.
我不确定,它是否正常工作,
我收到异常:Microsoft.Azure.Documents.RequestRateTooLargeException同时查询和插入大约4000条记录,
我使用相同的重试逻辑进行插入,其工作正常.我没有收到任何错误,也成功插入所有记录,但无法获取查询数据.
1> Aravind Kris..:
您还需要一个用于AggregateException的catch块,并检查AggregateException.InnerException是否为DocumentClientException并对StatusCode == 429执行相同的检查.由于查询执行是异步的,您可能会在AggregateException中包含限制异常.
如果您可以发布完整的repro,我们可以明确地确定问题.
另外值得注意的是,在处理限制异常时不要等待Timespan.Zero.而是查看你得到的响应,它将具有retry-after值.等待那段时间.
2> BMac..:
基于@aravind Ramachandra和@Ryan CrawCour上面/下面的答案,这就是我用来解决问题的方法.
public async Task SaveToDocDb(dynamic jsonDocToSave)
{
using (var client = new DocumentClient(endpoint, authKey))
{
var queryDOne= false;
while (!queryDone)
{
try
{
await client.CreateDocumentAsync(docCollectionlink, jsonDocToSave);
queryDOne= true;
}
catch (DocumentClientException documentClientException)
{
var statusCode = (int)documentClientException.StatusCode;
if (statusCode == 429 || statusCode == 503)
Thread.Sleep(documentClientException.RetryAfter);
else
throw;
}
catch (AggregateException aggregateException)
{
if(aggregateException.InnerException.GetType() == typeof(DocumentClientException)){
var docExcep = aggregateException.InnerException as DocumentClientException;
var statusCode = (int)docExcep.StatusCode;
if (statusCode == 429 || statusCode == 503)
Thread.Sleep(docExcep.RetryAfter);
else
throw;
}
else
throw;
}
}
}
}
@core虽然理论上你是对的,但实际上我已经将这段代码生产了近一年了,并且在工作中设置了一个杀戮时间 - 它从未达到过这个杀戮时间,因此意味着你的循环场景不可能发生在实践中.无论如何,对于其他人来说,建议微妙的修复/编辑答案,而不是声明完整的答案"坏代码"可能是有用的!