从Azure函数对Azure SQL数据库进行调用时遇到暂时性错误

时间:2019-01-14 18:05:19

标签: entity-framework-core azure-sql-database azure-functions azure-sdk-.net

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

我在Azure西欧具有以下设置

  • Azure SQL数据库 -Premium P2 250 DTU -公共端点,无VNET对等 -“允许访问Azure服务” =开

  • 天蓝色函数 -消费计划 -超时10分钟

  • Azure Blob存储 -热门

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

我经常遇到以下情况:并行处理多个Blob(一次最多调用5个异步Azure函数),并且Blob大小大于200K-500K记录时,.NET出现以下瞬态和连接错误核心实体框架:

1。 引发了一个异常,该异常很可能是由于瞬时故障引起的。考虑通过向“ UseSqlServer”调用中添加“ EnableRetryOnFailure()”来启用瞬态错误恢复能力。

2。 已成功与服务器建立连接,但是在登录前握手期间发生错误。 (提供者:SSL提供程序,错误:0-等待操作超时。)

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

4。 已成功与服务器建立连接,但是在登录前握手期间发生错误。 (提供者:SSL提供程序,错误:0-等待操作超时。)

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

同时,在测试过程中没有/没有报告Azure SQL数据库的运行状况事件,并且这些指标看起来很棒:MAX Workers <3.5%,Sum Success Connections <35,MAX Sessions Percentage <0.045%,Max日志UI百分比<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);
        }
    }
}

2 个答案:

答案 0 :(得分:0)

我找到了有关sql数据库瞬态错误的很好的文档:

从文档中:

  

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

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

带有SQL Server的实体框架实现了重试逻辑:

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

您可以在此处找到更多信息:

答案 1 :(得分:0)

删除并重新创建数据库用户,并确保填写用户名正下方的“登录名”框。这也将在较旧的SQL版本上解决相同的问题。