AppFabric在重启后无法很好地恢复。

48

好的,我已经成功部署了AppFabric,一切都很顺利,直到我们在网站上开始遇到间歇性异常:

ErrorCode < ERRCA0017 >:SubStatus < ES0007 >:有一个临时故障, 请稍后重试。(请求失败,因为服务器处于受限状态。)

起初我怀疑服务器内存不足(被限制的状态),但最终我得出了这不是问题的结论。 在事件日志中,我发现DistributedCacheService.exe偶尔会崩溃,并导致我在本地开发环境中重现错误的简单方法:

  • 启动网站,将一些东西添加到缓存中。
  • 重新启动“AppFabric Caching Service”。
  • ......然后我就开始收到错误信息。

如果我在重新启动服务之前执行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恢复正常?


4
请您发布完整的异常信息吗?细节在这里很重要 :-) - VdesmedT
你看过 http://msdn.microsoft.com/en-us/library/ff921020.aspx 吗? - VdesmedT
2
微软建议您为AppFabric缓存服务器设置单独的集群。http://msdn.microsoft.com/zh-cn/library/gg186017.aspx - np-hard
2个回答

2
简而言之,答案是否定的。
随着你添加额外节点,集群重新启动所需时间会增加,这使我相信这是一个节点同步过程需要时间。
你看到的异常确实是appfabric节点进入了受限状态。它将根据节点上高/低水位标记的设置而进入受限状态。我认为默认情况下高水位标记为90%,超过此时间后,它将开始根据缓存上设置的驱逐策略清除项目。通常应使用LRU(最近最少使用)策略,但如果缓存仍无法在设置的限制范围内运行,则会自我限制以避免使服务器崩溃。
如果你的应用程序能够优雅地处理此类事件,则可以获得好处。如果你的应用程序中集群配置中列出了所有节点,则在下一次尝试获取数据时,你的应用程序应该移动到下一个节点。我们使用重试循环寻找临时故障并重试3次。如果在3次尝试后错误仍然存在,则记录并返回null而不是异常。这使应用程序可以尝试访问其他节点或允许有问题的节点恢复时间:
 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));            
}

谢谢。我已经实现了类似的东西,如果AppFabric没有响应,我们的网站会回退到ASP.NET缓存。然而,我发现AppFabric需要花费10秒以上的时间才能确定它已经停止工作,所以在第一次失败后,我设置了一个10分钟的超时时间,所有随后的请求都不会发送到AppFabric。虽然有些笨拙,但它确实有效。 - Jakob Gade

-4

我曾经参与的一个项目也遇到了同样/类似的问题。在两周的时间里,我们一直苦苦思索并尝试各种方法来使我们的WCF服务(在Azure上)运行,但最终还是不得不联系微软。

微软的技术人员向我们提供了一个从网站运行时运行的(Power)Shell脚本,用于对AppFabric进行健康性+维护...这个脚本包含了我在Azure书籍中从未见过的内容,但确实可以很好地完成工作!

谢谢


8
但是你没有包含脚本 - 那么这个“答案”中包含的答案是什么? - jball
请提供脚本,因为我遇到了类似的问题。 - Somedeveloper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接