【问题标题】:Correct Implementation of Transient Fault Handling (Azure)正确实施瞬态故障处理 (Azure)
【发布时间】:2015-03-04 00:47:47
【问题描述】:

过去一天左右,我一直在尝试在 Azure SQL 数据库上实现瞬态故障处理。尽管我与 DB 建立了有效连接,但我不相信它会按预期处理瞬态故障。

到目前为止,我的方法涉及

public static void SetRetryStratPol()
{
    const string defaultRetryStrategyName = "default";

    var strategy = new Incremental(defaultRetryStrategyName, 3, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
    var strategies = new List<RetryStrategy> { strategy };
    var manager = new RetryManager(strategies, defaultRetryStrategyName);
    RetryManager.SetDefault(manager);
    retryPolicy = new RetryPolicy<SqlDatabaseTransientErrorDetectionStrategy>(strategy);
    retryPolicy.Retrying += (obj, eventArgs) =>
                            {
                                var msg = String.Format("Retrying, CurrentRetryCount = {0} , Delay = {1}, Exception = {2}", eventArgs.CurrentRetryCount, eventArgs.Delay, eventArgs.LastException.Message);
                                System.Diagnostics.Debug.WriteLine(msg);
                            };
}

我从Global.asaxApplication_Start() 调用该方法。 [retryPolicy 是静态类上的全局静态变量,它也包括下一个方法。]

然后我有一个方法

public static ReliableSqlConnection GetReliableConnection()
{
    var conn = new ReliableSqlConnection("Server=...,1433;Database=...;User ID=...;Password=...;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;", retryPolicy);

    conn.Open();

    return conn;
}

然后我就用这个方法

using (var conn = GetReliableConnection())
using (var cmd = conn.CreateCommand())
{
    cmd.CommandText = "SELECT COUNT(*) FROM ReliabilityTest";

    result = (int) cmd.ExecuteScalarWithRetry();

    return View(result);
}

到目前为止,这是可行的。然后,为了测试重试策略,我尝试使用错误的用户名(来自here 的建议)。

但是当我单步执行该代码时,光标会立即跳转到我的 catch 语句,并带有

用户“[我的用户名]”登录失败。

我原以为这个异常只会在几秒钟后被捕获,但根本不会产生延迟。

此外,我还尝试使用实体框架,完全遵循 this post,但得到相同的结果。

我错过了什么?是否有配置步骤,或者我是否错误地引发了瞬态故障?

【问题讨论】:

    标签: c# azure azure-sql-database dbconnection


    【解决方案1】:

    瞬态故障处理块用于处理瞬态错误。由于用户名/密码错误而导致登录失败当然不是其中之一。来自这个网页:http://msdn.microsoft.com/en-us/library/dn440719%28v=pandp.60%29.aspx

    什么是瞬态故障?

    当应用程序使用服务时,可能会发生错误,因为 临时条件,例如间歇性服务, 基础设施级故障、网络问题或显式限制 服务;这些类型的错误更频繁地发生 基于云的服务,但也可能出现在本地解决方案中。如果 您稍后重试该操作(可能只有几个 毫秒后)操作可能会成功。这些类型的错误 条件称为瞬态故障。瞬态故障 通常很少发生,在大多数情况下,只有少数 操作成功需要重试。

    您可能需要检查此应用程序块 (http://topaz.codeplex.com/) 的源代码,并查看从 SQL 数据库返回的哪些错误代码被视为暂时错误并因此重试。

    您始终可以扩展功能并将登录失败作为暂时性错误之一来测试您的代码。

    更新

    请在此处查看源代码:http://topaz.codeplex.com/SourceControl/latest#source/Source/TransientFaultHandling.Data/SqlDatabaseTransientErrorDetectionStrategy.cs。这就是重试魔法发生的地方。你可以做的是创建一个类(我们称之为CustomSqlDatabaseTransientErrorDetectionStrategy)并将整个代码从链接复制到这个类)。然后出于测试目的,您可以将login failed 场景添加为瞬态错误之一,并在您的应用程序中使用此类而不是SqlDatabaseTransientErrorDetectionStrategy

    【讨论】:

    • 这是我的怀疑之一。但是,我在问题中引用的博客文章是 6 个月前由 Azure MVP 撰写的,他通过更改用户名来诱导重试策略,然后提供证据证明此更改已调用重试策略。你有任何瞬态故障处理的经验,你能建议任何其他方法来测试它吗?
    • 更新了我的答案。 HTH。
    • 我确实四处寻找源代码,但没有找到,所以感谢链接。我按照您的建议做了,发现我调用的错误代码不是被视为瞬态故障的类型。但是,我可以看到它根据 RetryStrategy 反复点击 IsTransient 方法。所以......我现在很满意我的 OP 中的代码是有效的,我只是试图错误地触发和验证它。感谢您的帮助。
    • 请注意,Microsoft 自己不断地添加到暂时性错误列表中。所以我认为它不能被认为是权威的,甚至在某个时间点都不能,因为在 MS 的不同团队做不同的事情。我们坚持了一段时间,但每次我们认为我们取得了进展时,都会发生一个未被覆盖的新错误。所以我们所做的是重试所有错误,有一些严重错误被我们“列入白名单”为不值得重试。
    猜你喜欢
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-06
    相关资源
    最近更新 更多