You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure App Service连接SQL Server登录后阶段超时问题求助

问题描述

我在Azure部署了S1层且启用Always On的App Service,连接Azure SQL Server数据库,服务包含多个与库交互的定时触发WebJobs。

每次执行SQL请求都会触发以下异常:

Microsoft.Data.SqlClient.SqlException (0x80131904): Connection Timeout Expired. The timeout period elapsed during the post-login phase. The connection could have timed out while waiting for server to complete the login process and respond; Or it could have timed out while attempting to create multiple active connections. The duration spent while attempting to connect to this server was - [Pre-Login] initialization=124; handshake=49; [Login] initialization=0; authentication=0; [Post-Login] complete=14011;

相关环境与排查信息:

  • SQL Server层级:General Purpose - Serverless: Standard-series (Gen5), 1 vCore
  • 异常触发无数据量限制,处理5条数据时也会出现
  • App Insights显示SQL请求耗时14秒后报错
  • 本地使用同一数据库运行应用完全正常,可处理数万条数据,排除数据库配置问题
  • 已确认SQL Server防火墙启用「Allow Azure services and resources to access this server」选项
  • 使用EF Core,DbContext注册代码:
    collection
            .AddDbContext<ApplicationDbContext>(options =>
                options.UseSqlServer(
                    context.Configuration.GetConnectionString("Database"),
                    sqlServerOptions =>
                    {
                        sqlServerOptions.CommandTimeout(3600);
                        sqlServerOptions.EnableRetryOnFailure(5, TimeSpan.FromSeconds(30), null);
                    }))
    
  • 所有使用DB上下文的服务均注册为scoped
  • 猜测是连接生命周期问题:WebJob启动后立即执行正常,但Azure中运行半天后崩溃

解决方案建议

1. 适配WebJob场景调整DbContext生命周期

WebJob属于无HTTP请求的后台任务,默认Scoped生命周期在这类场景下易导致DbContext实例无法被正确回收,引发连接池耗尽:

  • 将DbContext注册为Transient:
    collection.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(
            context.Configuration.GetConnectionString("Database"),
            sqlServerOptions =>
            {
                sqlServerOptions.CommandTimeout(3600);
                sqlServerOptions.EnableRetryOnFailure(5, TimeSpan.FromSeconds(30), null);
            }),
        ServiceLifetime.Transient); // 指定Transient生命周期
    
  • 或在WebJob触发方法中手动控制上下文生命周期:
    using (var scope = serviceProvider.CreateScope())
    {
        var dbContext = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
        // 执行数据库操作
    }
    

2. 优化SQL Serverless配置

Serverless层级会因闲置自动暂停恢复,冷启动或资源限制可能导致登录阶段超时:

  • 延长服务器暂停延迟时间,减少频繁冷启动的概率
  • 临时切换到非Serverless层级(如General Purpose Provisioned)测试,确认是否为Serverless特性导致

3. 调整连接池参数

在连接字符串中添加连接池配置,避免连接耗尽或过度创建:

Server=tcp:{servername}.database.windows.net,1433;Initial Catalog={dbname};Persist Security Info=False;User ID={username};Password={password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Max Pool Size=100;Min Pool Size=5;
  • Max Pool Size:限制连接池最大连接数,避免超出SQL Server承载能力
  • Min Pool Size:维持少量空闲连接,减少重新创建连接的开销

4. 控制WebJob并发

多个定时WebJobs同时触发会瞬间创建大量连接,加剧超时问题:

  • 调整WebJob的并发限制,避免同时运行过多实例
  • 错开不同定时任务的触发时间,降低并发压力

5. 启用EF Core连接日志

添加连接日志追踪连接的创建与释放过程,定位是否存在连接泄漏:

options.UseSqlServer(...)
       .LogTo(Console.WriteLine, new[] { DbLoggerCategory.Database.Connection.Name }, LogLevel.Debug);

内容的提问来源于stack exchange,提问作者Flatternschu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 07:33:14