AppFabric 无法从重新启动中很好地恢复
Posted
技术标签:
【中文标题】AppFabric 无法从重新启动中很好地恢复【英文标题】:AppFabric doesn’t recover well from restart 【发布时间】:2011-11-20 23:04:08 【问题描述】:好的,我已经成功部署了 AppFabric,一切都运行良好,直到网站开始出现间歇性异常:
ErrorCode :SubStatus :有临时故障。 请稍后重试。 (请求失败,因为服务器在 节流状态。)
起初我怀疑服务器内存不足(节流状态),但我最终得出结论,这不是问题所在。在事件日志中,我发现 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 更快地重新站起来?
【问题讨论】:
能否发布完整的例外情况?细节很重要:-) 你看过msdn.microsoft.com/en-us/library/ff921020.aspx MS 建议你有一个单独的集群用于 appfabric 缓存服务器msdn.microsoft.com/en-us/library/gg186017.aspx 【参考方案1】:简而言之,答案是否定的。
随着您添加额外的节点,集群重启所需的时间会增加,这让我相信这是一个需要时间的节点同步过程。
您看到的异常确实是 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。笨拙,但它有效。【参考方案2】:我参与的一个项目也发生了同样/类似的问题。经过两周的摸索和尝试一切以使我们的 WCF 服务运行(在 Azure 上)均未成功,我们最终致电 Microsoft。
Microsoft 的技术人员确实为我们提供了一个 (Power)Shell 脚本,该脚本从站点的运行时运行,该脚本执行 AppFabric 的健康和维护...该脚本包含我在 Azure 书籍中没有看到的内容全部,但它确实完成了工作!
谢谢
【讨论】:
但是您没有包含脚本 - 那么这个“答案”中包含的答案是什么? 请提供脚本,因为我有类似的问题。以上是关于AppFabric 无法从重新启动中很好地恢复的主要内容,如果未能解决你的问题,请参考以下文章
从Windows磁盘修复文件(FOUND.000)中恢复文件