AppFabric无法从重启中恢复良好

时间:2011-09-20 10:11:34

标签: c# .net asp.net vb.net appfabric

好吧,我已经成功部署了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更快地恢复原状?

2 个答案:

答案 0 :(得分:2)

简而言之,答案是否定的。

当您添加额外节点时,群集重新启动的时间会增加,这会让我相信这是一个花费时间的节点同步过程。

您看到的异常确实是appfabric节点进入限制状态。它将进入限制状态,具体取决于您在节点上设置高/低水印的方式。我认为默认情况下,高水位标记是90%,此时它将开始驱逐在缓存上设置的驱逐策略上的项目。您通常应该使用LRU(最近最少使用),但如果缓存仍然无法在限制范围内运行,它将自行调整以防止服务器停机。

如果您的申请能够优雅地处理此类活动,那么您的申请将会受益。如果您的应用程序的群集配置中列出了所有节点,则您的应用程序应在下次尝试获取数据时转到下一个节点。我们使用重试循环查找临时故障并重试3次。如果错误持续3次后我们记录并返回null,而不是exeption。这允许应用程序尝试访问不同的节点或允许问题节点有时间恢复:

 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));            
}

答案 1 :(得分:-4)

我工作的其中一个项目发生了同样/类似的问题。经过两个星期的努力,我们没有成功地尝试所有东西来运行我们的WCF服务(在Azure上),我们最终打电话给微软。

来自微软的技术人员确实为我们提供了一个(Power)Shell脚本,该脚本是从该网站的运行时运行的,该脚本执行AppFabric的健康+维护......该脚本包含我在Azure书籍上没有看到的内容。所有,但它确实正确地完成了工作!

由于