Подтвердить что ты не робот

AppFabric не восстанавливается после перезагрузки

Хорошо, Ive успешно развернуло AppFabric, и все работало хорошо, пока мы не начали получать прерывистое исключение на веб-сайте:

ErrorCode < ERRCA0017 > : SubStatus < ES0007 > : Временная ошибка. Повторите попытку позже. (Ошибка запроса, поскольку сервер находится в дросселированное состояние.)

Сначала я подозревал, что сервер работает на низкой памяти (дросселированное состояние), но в конце концов я пришел к выводу, что это не проблема. В журнале событий я обнаружил, что DistributedCacheService.exe разбился время от времени, и это привело меня к простому способу повторного создания ошибки в моей локальной среде разработки:

  • Запустите веб-сайт, добавьте несколько вещей в кеш.
  • Перезапустите службу кэширования AppFabric.
  • ... и я начинаю получать ошибку.

Если я делаю Get-CacheClusterHealth ПЕРЕД повторным запуском службы, она выглядит примерно так:

NamedCache = MyCacheName
    Healthy              = 100,00
    UnderReconfiguration = 0,00
    NotPrimary           = 0,00
    NoWriteQuorum        = 0,00
    Throttled            = 0,00

После перезапуска:

Unallocated named cache fractions
---------------------------------

NamedCache = MyCacheName
    Unallocated fraction     = 100,00

Пока я получаю этот результат от Get-CacheClusterHealth, сайт не работает. Из того, что я могу сказать, он исправляет себя через некоторое время (10 + минут).

Есть ли способ быстрее вернуть AppFabric на ноги?

4b9b3361

Ответ 1

Короче говоря, нет.

Время, затрачиваемое кластером на перезагрузку, увеличивается при добавлении дополнительных узлов, что заставляет меня думать, что это процесс синхронизации node, который занимает время.

Исключением, которое вы видите, действительно является приложением node, входящим в дроссельное состояние. Он войдет в дроссельное состояние, в зависимости от того, как у вас установлены водяные знаки с высоким/низким значением на node. Я думаю, что по умолчанию показатель высокой воды составляет 90%, после этого он начнет высекать элементы, определяющие политику выселения, установленную в кеше. Обычно вы должны использовать LRU (совсем недавно), но если кеш все еще не может работать в пределах установленных ограничений, он будет дросселировать себя, чтобы не довести ваш сервер.

Ваше приложение принесет пользу, если оно сможет обработать такие события изящно. Если у вас есть все узлы, перечисленные в конфигурации кластера вашего приложения, ваше приложение должно перейти к следующему node при следующей попытке получить данные. Мы используем цикл повтора, который ищет временный сбой и повторяет попытку 3 раза. Если после 3-х ошибок ошибка сохраняется, мы регистрируем и возвращаем значение null, а не exeption. Это позволяет приложению пытаться получить доступ к другому node или разрешить проблему node для восстановления:

 private object WithRetry(Func<object> method)
    {
        int tryCount = 0;
        bool done = false;
        object result = null;
        do
        {
            try
            {
                result = method();
                done = true;
            }
            catch (DataCacheException ex)
            {
                if (ex.ErrorCode == DataCacheErrorCode.KeyDoesNotExist)
                {
                    done = true;
                }
                else if ((ex.ErrorCode == DataCacheErrorCode.Timeout ||
                ex.ErrorCode == DataCacheErrorCode.RetryLater ||
                ex.ErrorCode == DataCacheErrorCode.ConnectionTerminated)
                && tryCount < MaxTryCount)
                {                        
                    tryCount++;
                    LogRetryException(ex, tryCount);
                }
                else
                {
                    LogException(ex);
                    done = true;
                }
            }
        }
        while (!done);


 return result;
}

И это позволяет нам сделать следующее:

private void AF_Put(string key, object value)
{
    WithRetry(() => defaultCache.Put(key, value));
}

или

private object AF_Get(string key)
{
    return WithRetry(() => defaultCache.Get(key));            
}

Ответ 2

Эта же/аналогичная проблема произошла с одним из проектов, над которыми я работал. После двух недель царапин на головах и безуспешно пробовав все, чтобы наши сервисы WCF работали (на Azure), мы в конечном итоге позвонили в Microsoft.

Техники из Microsoft предоставили нам (Power) Shell script, который запускается со среды выполнения сайта, которая делает здоровье + обслуживание AppFabric... У script были вещи, которых я не видел на лазурных книгах вообще, но он действительно выполнил эту работу правильно!

Спасибо