AppFabric无法从重新启动恢复
好的,我已经成功部署了AppFabric,并且一切都很好,直到我们开始在网站上发生间歇性的exception:
ErrorCode <ERRCA0017>:SubStatus <ES0007>:存在临时故障。 请稍后重试。 (请求失败,因为服务器处于限制状态。)
起初我怀疑服务器内存不足(节stream状态),但我最终认为这不是问题。 在事件日志中,我发现DistributedCacheService.exe随时崩溃,并导致我在本地开发环境中重新生成错误的一种简单方法:
- 启动网站,添加一些东西到caching中。
- 重新启动“AppFabriccaching服务”。
- …我开始得到错误。
如果我在重新启动服务之前执行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更快恢复?
总之答案是否定的。
当您添加额外的节点时,群集重新启动的时间会增加,这导致我相信这是需要花费时间的节点同步过程。
你看到的exception确实是进入节制状态的appfabric节点。 它将进入节stream状态,具体取决于节点上设置的高/低水印的方式。 我认为默认情况下,高水位是90%,此时它将开始驱逐在caching上设置的驱逐策略上的项目。 您通常应该使用LRU(最近最less使用),但是如果caching仍然无法在设置的限制范围内运行,它将自行调节以免导致服务器closures。
如果能够优雅地处理这样的事件,你的应用程序将会受益。 如果您的应用程序的群集configuration中列出了所有节点,则应用程序应在下一次尝试获取数据时转到下一个节点。 我们使用一个重试循环寻找临时故障并重试3次。 如果3次后错误仍然存在,我们logging并返回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)); }
我所从事的其中一个项目也出现了同样的问题。 经过两个星期的考验,我们没有成功尝试所有的WCF服务(在Azure上),我们最终打电话给微软。
微软的技术人员向我们提供了一个(Power)Shell脚本,该脚本从站点的运行时运行,执行AppFabric的运行状况和维护…该脚本包含了我从未在Azure书籍上看到过的内容,但它确实正确完成了工作!
谢谢