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)中恢复文件

grpc:服务器重新启动后大约 15 秒无法恢复连接

使用 Ctrl+C 停止 Debezium 连接器并再次重新启动连接器后连接器不起作用

JPanel 使用透明 JFrame 不能很好地重新绘制

在文本中很好地打印决策树/使用自定义控件 [r]

在 Django 的管理界面中很好地显示日期