首页 > 解决方案 > 从 Azure Function 调用 Azure SQL 数据库时出现暂时性错误

问题描述

我们正在使用 .NET Core 2.1 和 Entity Framework Core 2.1.1

我在 Azure 西欧有以下设置

多个 blob 上传到 Azure Blob 存储,Azure Functions(最多同时 5 个)通过 Azure 事件网格触发。Azure Functions 根据存储在 Azure SQL DB 中的元数据检查 Blob 的结构。每个 blob 最多包含 500K 记录和 5 列有效负载数据。对于每条记录,Azure Functions 都会对 Azure SQL DB 进行调用,因此不会进行缓存。

我经常在并行处理多个 blob 时(最多同时调用 5 个异步 Azure Functions),并且当 blob 大小大于 200K-500K 记录时,来自 .NET Core Entity Framework 的以下瞬态和连接错误:

1. 引发了一个异常,可能是由于暂时性故障。考虑通过将“EnableRetryOnFailure()”添加到“UseSqlServer”调用来启用瞬时错误恢复能力。

2. 与服务器成功建立连接,但登录前握手时出错。(提供者:SSL 提供者,错误:0 - 等待操作超时。)

3. 连接超时。尝试使用登录前握手确认时超时时间已过。这可能是因为登录前握手失败或服务器无法及时响应。尝试连接到路由目标时发生此故障。尝试连接到原始服务器所花费的持续时间是 - [Pre-Login] 初始化 = 13633;握手=535;[登录] 初始化=1;身份验证=0;[登录后] 完成=156;尝试连接到此服务器所花费的持续时间是 - [登录前] 初始化 = 5679;握手=2044;

4. 与服务器成功建立连接,但在登录前握手过程中出错。(提供者:SSL 提供者,错误:0 - 等待操作超时。)

  1. 服务器提供了路由信息,但超时已过期。

同时,在测试期间,Azure SQL 数据库报告了任何/没有健康事件,指标看起来很棒:MAX Workers < 3.5%,Sum Success Connections < 35,MAX Sessions Percentage < 0.045%,Max Log UI percent < 0.024%,总失败连接数 = 0,最大 DTU < 10%,最大数据 IO < 0.055%,最大 CPU < 10%。

在 Azure SQL DB (sys.database_connection_stats_ex) 上运行连接统计信息:没有失败、中止或受限制的连接。

select *
from sys.database_connection_stats_ex
where start_time >= CAST(FLOOR(CAST(getdate() AS float)) AS DATETIME)
order by start_time desc

有没有人在使用 .Net Core Entity Framework 和 Azure SQL 数据库时遇到过类似的问题。为什么我会收到这些暂时性错误,为什么 Azure SQL 数据库指标看起来那么好,根本没有反映存在问题?

非常感谢您的帮助。

using Microsoft.EntityFrameworkCore;

namespace MyProject.Domain.Data
{
    public sealed class ApplicationDbContextFactory : IApplicationDbContextFactory
    {
        private readonly IConfigurationDbConfiguration _configuration;
        private readonly IDateTimeService _dateTimeService;

        public ApplicationDbContextFactory(IConfigurationDbConfiguration configuration, IDateTimeService dateTimeService)
        {
            _configuration = configuration;
            _dateTimeService = dateTimeService;
        }

        public ApplicationDbContext Create()
        {
            //Not initialized in ctor due to unit testing static functions.
            var options = new DbContextOptionsBuilder<ApplicationDbContext>()
                .UseSqlServer(_configuration.ConfigurationDbConnectionString).Options;

            return new ApplicationDbContext(options, _dateTimeService);
        }
    }
}

标签: entity-framework-coreazure-sql-databaseazure-functionsazure-sdk-.net

解决方案


我发现这个关于 sql 数据库瞬态错误的好文档:

从文档中:

瞬态错误有一个很快就会自行解决的根本原因。临时错误的一个偶然原因是 Azure 系统快速转移硬件资源以更好地平衡各种工作负载。大多数这些重新配置事件在不到 60 秒内完成。在此重新配置时间范围内,您可能会遇到与 SQL 数据库的连接问题。应构建连接到 SQL 数据库的应用程序以预期这些暂时错误。要处理它们,请在其代码中实现重试逻辑,而不是将它们作为应用程序错误呈现给用户。

然后详细解释了如何为瞬态错误构建重试逻辑。

带有 SQL 服务器的实体框架实现了重试逻辑:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer("<connection string>", options => options.EnableRetryOnFailure());
}

您可以在这里找到更多信息:


推荐阅读