1

我有两个 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 毫秒)

4

1 回答 1

2

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

从这些文章:

瞬态故障的原因

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

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

如果您使用ADO.NET访问 SQL 数据库(而不是通过实体框架),Microsoft 模式和实践组有一个瞬态故障处理应用程序块,它可以为您完成所有工作。您只需设置重试策略——重试查询或命令的次数以及尝试之间的等待时间——然后将 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());
    }
}
于 2016-03-13T09:33:58.123 回答