Управление поиском Azure 503

Есть ли хорошо известный шаблон для управления ServiceUnavailable? Я НЕ очень доволен чем-то вроде этого

catch (CloudException e) when (System.Net.HttpStatusCode.ServiceUnavailable.Equals(e.Response?.StatusCode))
{
    var howMuchWait = TimeSpan.FromMinutes(1);
    if (e.Response.Headers.TryGetValue("Retry-After", out var hValue))
    {
        if(RetryConditionHeaderValue.TryParse(hValue.FirstOrDefault(), out var time) && time.Delta.HasValue)
        {
            howMuchWait = time.Delta.Value;
        }
    }
    logger.LogWarning(() => $"Service Unavailable... Let him rest a bit, I will wait for {howMuchWait}.");
    await Task.Delay(howMuchWait);
    return indexEntities.Select(x => (string)x[indexKeyFieldName]).ToList();
}

Этот код просто задерживает текущий вызов к нему, но не предотвращает вызовы из других потоков. Теперь я реализую что-то другое, используя Stopwatch, и хотел бы знать, есть ли известный шаблон. ПРИМЕЧАНИЕ: все с использованием SDK.


person Fabio Maulo    schedule 05.07.2017    source источник


Ответы (1)


При управлении для 503-х лучше всего реализовать механизм постепенного отката, а не фиксированную временную задержку. Например, начните с 1 секунды, затем 2, затем 4, затем 8 и т. Д. Основная причина этого заключается в том, что если вы отправляете много работы в Поиск Azure, лучше позволить ему наверстать упущенное, а не чтобы постоянно пытаться послать ему больше работы.

Кстати, для других, читающих это, иногда вы можете подумать, что это хорошая идея - добавить разделы, когда вы видите эти 503 (обычно для массовой загрузки), чтобы предоставить больше ресурсов, хотя на самом деле это может вызвать больше 503, поскольку это дополнительная работа, которую необходимо проделать службе, чтобы настроить разделы. Если вы действительно считаете, что вам нужно больше разделов, лучше сделать это до того, как вы сделаете работу, а затем, при необходимости, уменьшить масштаб.

Кроме того, еще одно замечание: если вы использовали пакет SDK для Azure Search .NET, повторная попытка уже интегрирована. У Брюса есть полезная информация по этому поводу: Azure Search RetryPolicy

person Liam Cavanagh - MSFT    schedule 05.07.2017
comment
Привет, Лиам. Я знаю, что происходит при попытке отправить больше работы в службу, и по этой причине я бы избегал даже RetryPolicy (читайте это как: не настаивает (повторить попытку), если вы знаете, что я занят). Я работаю примерно так: private async Task<IEnumerable<string>> InsertBatch(ISearchIndexClient index, List<Document> indexEntities) { if(IsInDoNotDisturb()) { return indexEntities.Select(x => (string)x[indexKeyFieldName]).ToList(); } - person Fabio Maulo; 05.07.2017
comment
И еще кое-что ... Лиаму / Брюсу было бы действительно полезно иметь заголовок Retry-After с 503, чтобы дать нам возможность уважать его. - person Fabio Maulo; 05.07.2017