Azure WebJob数据库连接错误仅在某些情况下

时间:2016-03-12 04:04:42

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

我有两个Azure WebJobs。第一个接收传入消息,告诉它抓取PDF并将其分解为单个页面图像,然后为第二个WebJob排队另一条消息以处理各个页面。它在我们的质量控制实例上运行良好,但是当我们尝试转向生产时,我开始在第二个工作上遇到奇怪的错误,但不是一贯的。第一个作业运行并将文件分成页面图像。这工作正常。我已确认每个页面图像都已创建,每个页面消息都会排队。但是,对于第二个作业,只有一些消息被正确处理。其余的在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作为代码的第一行。对于那些成功处理的工作,我看到了这个写作线。对于那些失败的人,我什么也看不见。这几乎就像工作没有真正正确启动。 (失败的工作也有一个非常短的运行时间50-100ms)

1 个答案:

答案 0 :(得分:2)

我在某些工作中遇到了同样的问题,而且我已经在这些文章中找到了解决方案:

来自这些文章:

暂时失败的原因

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

使用智能重试/退避逻辑来缓解瞬态故障的影响

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

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.
    }
}

当您使用实体框架时,您通常不直接使用SQL连接,因此您无法使用此模式和实践包,但实体框架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());
    }
}
相关问题