首页 > 解决方案 > 为什么当我使用生产(基本应用服务)插槽时 Azure 应用服务不能可靠地读取我的连接字符串

问题描述

我有一个要部署到 Azure 应用服务的 ASP.NET Core 2.1 API。我使用 Azure SQL Server 作为我的后备数据库。

下面是应用服务(基本)应用程序设置刀片的屏幕截图。这显示 .Net Framework 版本设置为 4.7。

在此处输入图像描述

我设置了带有部署槽的应用服务。

对于每个部署槽,我在“应用程序设置”刀片中都有连接字符串,其中包含特定于该槽数据库的值(每个槽有 3 个不同的数据库,并且有 3 个槽)。

QA 和 DEV 插槽几个月来一直运行良好,但是,我们现在正在使用生产插槽(应用服务基础)将 API 推出到 beta 站点,并且似乎应用服务的生产插槽中的连接字符串没有被可靠阅读。具体来说,似乎没有可靠地读取第二个和第三个连接字符串。

这是显示连接字符串的应用服务 --> 应用程序设置刀片的屏幕截图;

在此处输入图像描述

如您所见,我为每个检查了插槽设置。HangfireDbConnectioinString 总是无法读取,并且 UspsReferenceDbConnectionString 似乎不稳定,但这可能是因为 Hangfire 数据库未设置并引发异常。

我对 QA 和 DEV 插槽使用相同的设置,它们工作正常。此问题仅发生在生产槽(基本应用服务)设置中。

如果我在我的 API 的 AppSettings.json 文件中包含实际连接字符串并将其重新部署到生产槽,则 API 能够正确访问数据库。当然,这不是一个理想的解决方案,因为它将我的连接字符串置于源代码控制中。

如果它很重要,这里是基本应用服务扩展刀片的屏幕截图。

在此处输入图像描述

下面是我的 Startup.cs 中设置数据库的代码部分。

    protected virtual void ConfigureDatabase(IServiceCollection services)
    {

        var sqlTransientErrors = new List<int>() { 10928, 10929, 10053, 10054, 10060, 40197, 40540, 40613, 40143, 64 };

        // Configure DBContexts with resilient SQL connections to SQL Server
        services.AddDbContext<ManifestContext>(options =>
        {
            options.UseSqlServer(Configuration.GetConnectionString("ManifestDbConnectionString"),
                sqlOptions =>
                {
                    sqlOptions.EnableRetryOnFailure(5, TimeSpan.FromSeconds(30),
                        sqlTransientErrors);
                    sqlOptions.CommandTimeout(Convert.ToInt32(Configuration["DbSettings:ManifestDbCommandTimeout"]));
                });
        });

        services.AddDbContext<UspsReferenceContext>(options =>
        {
            options.UseSqlServer(Configuration.GetConnectionString("UspsReferenceDbConnectionString"),
                sqlOptions =>
                {
                    sqlOptions.EnableRetryOnFailure(5, TimeSpan.FromSeconds(30), sqlTransientErrors);
                    sqlOptions.CommandTimeout(Convert.ToInt32(Configuration["DbSettings:UspsReferenceDbCommandTimeout"]));
                });
        });

        // Hangfire persistence store for background tasks
        services.AddHangfire(configuration =>
            configuration.UseSqlServerStorage(Configuration.GetConnectionString("HangfireDbConnectionString")));


    }

如您所见,我正在使用 Configuration.GetConnectionString("HangfireDbConnectionString") 从 Configuration 中检索连接字符串。

有任何想法吗?

标签: c#azureasp.net-core-2.1azure-app-service-envrmntazure-deployment-slots

解决方案


这是几年后的事了,您的问题并不清楚您是直接部署到生产环境还是部署到部署槽之一然后切换到生产环境。

但我目前正在调查一个类似的问题,我认为正在发生的事情是 Startup.cs 代码只运行一次,并且在部署槽交换后不会重新运行,因为应用程序已经预热。由于您在 startup.cs 中读取配置一次并将其保存在应用程序加载(而不是每次需要时重新读取),您可能会从部署槽加载值,而不是在切换到生产后替换它们。


推荐阅读