【问题标题】:Azure WebJob DB Connection Error Only on some instances仅在某些实例上出现 Azure WebJob DB 连接错误
【发布时间】:2016-06-27 11:43:03
【问题描述】:

我有两个 Azure WebJobs。第一个接收一条传入消息,告诉它获取 PDF 并将其分解为单独的页面图像,然后将另一条消息排队供第二个 WebJob 处理单独的页面。它在我们的 QC 实例上运行良好,但是当我们尝试转移到生产环境时,我开始在第二份工作中遇到奇怪的错误,但并非始终如一。第一个作业运行并将文件分解为页面图像。那工作正常。我已经确认每个页面图像都被创建并且每个页面消息都被排队。但是,对于第二个作业,只有部分消息得到正确处理。其余在 WebJob 诊断中显示此错误:

Microsoft.Azure.WebJobs.Host.FunctionInvocationException:Microsoft.Azure.WebJobs.Host.FunctionInvocationException:执行函数时出现异常:Functions.ProcessBatchPage ---> System.Data.SqlClient.SqlException:网络相关或实例-建立与 SQL Server 的连接时发生特定错误。服务器未找到或无法访问。验证实例名称是否正确以及 SQL Server 是否配置为允许远程连接。 (提供程序:SQL 网络接口,错误:52 - 无法找到本地数据库运行时安装。验证 SQL Server Express 已正确安装并且本地数据库运行时功能已启用。)---> System.ComponentModel.Win32Exception:系统找不到指定的文件

但奇怪的是,这个错误提到了本地数据库运行时和 SQL Server Express,而我的代码中的任何地方都没有引用。系统指向 Azure SQL DB。这项工作是 ADO.Net,我对连接字符串进行了硬编码,以尝试消除基于配置的连接字符串的任何问题。但奇怪的是,它只发生在消息的特定部分。其他处理完美。

最后,我在本地调试工作(仍然指向 Azure 上的真实队列和数据库)并遇到了同样的问题。但是该作业会输出一个控制台行,其中作业 ID 作为代码的第一行。对于那些成功处理的作业,我看到了这个 writeline。对于那些失败的人,我什么都没看到。这几乎就像工作并没有真正正确启动。 (失败的作业也有很短的运行时间 50-100 毫秒)

【问题讨论】:

  • 您可以发布正在部署到 Azure 的 app.config 吗?如果您使用的是 EF,能否发布您如何设置连接字符串?
  • 根本不使用 EF。我在 webjob 中遇到了 EF 问题,所以我直接用 ADO.net 重写了。它有一个带有硬编码连接字符串的 SQLConnection 语句。以前我在 app.config 中有 CS,但在 webjob functions.cs 中对其进行了硬编码以尝试消除此问题。

标签: azure azure-webjobs azure-webjobssdk dbconnection azure-sql-database


【解决方案1】:

我在一些工作中遇到了同样的问题,我通过这些文章找到了解决方案:

来自这些文章:

暂时性故障的原因

在云环境中,您会发现失败和断开的数据库连接会定期发生。这部分是因为与 Web 服务器和数据库服务器具有直接物理连接的本地环境相比,您需要使用更多的负载平衡器。此外,有时当您依赖多租户服务时,您会看到对该服务的调用变慢或超时,因为使用该服务的其他人正在重击它。在其他情况下,您可能是过于频繁地访问服务的用户,而服务故意限制您(拒绝连接)以防止您对服务的其他租户产生不利影响。

使用智能重试/回退逻辑来减轻瞬时故障的影响

Microsoft Patterns & Practices 小组有一个Transient Fault Handling Application Block,如果您使用 ADO.NET 进行 SQL 数据库访问(而不是通过实体框架),它会为您完成所有工作。您只需设置重试策略 - 重试查询或命令的次数以及尝试之间等待多长时间 - 并将 SQL 代码包装在 using 块中:

public void HandleTransients()
{
   var connStr = "some database";
   var _policy = RetryPolicy.Create < SqlAzureTransientErrorDetectionStrategy(
    retryCount: 3,
    retryInterval: TimeSpan.FromSeconds(5));

    using (var conn = new ReliableSqlConnection(connStr, _policy))
    {
        // Do SQL stuff here.
    }
}

当您使用 Entity Framework 时,您通常不直接使用 SQL 连接,因此您不能使用此 Patterns and Practices 包,但 Entity Framework 6 正确构建了这种重试逻辑进入框架。以类似的方式指定重试策略,然后 EF 在访问数据库时使用该策略。

要在 Fix It 应用中使用此功能,我们所要做的就是添加一个派生自 DbConfiguration 的类并打开重试逻辑。

// EF follows a Code based Configuration model and will look for a class that
// derives from DbConfiguration for executing any Connection Resiliency strategies
public class EFConfiguration : DbConfiguration
{
    public EFConfiguration()
    {
        AddExecutionStrategy(() => new SqlAzureExecutionStrategy());
    }
}

【讨论】:

  • 谢谢托马斯。我正在使用 ADO.net 并添加 TFHAB 代码似乎可以清除此错误。虽然我应该一直在使用它,但它返回的与 SQL Server Express 相关的错误让我大吃一惊!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-03
相关资源
最近更新 更多