如何以编程方式将Azure Web作业/应用服务连接到Azure远程数据库?

t9aqgxwy  于 2023-06-24  发布在  其他
关注(0)|答案(1)|浏览(85)

bounty还有4天到期。此问题的答案有资格获得+50声望奖励。E. A. Bagby希望引起更多关注这个问题。

我创建了一个基于以下内容的WebJob:
https://learn.microsoft.com/en-us/azure/app-service/webjobs-sdk-get-started
WebJob用于自动创建SQLite数据库,然后使用来自Azure数据库的数据填充数据库。所有Azure数据库都具有相同的结构。为了进行同步,我使用Microsoft.Datasync.Client和Microsoft.Datasync.Client.SQLiteStore,基于:
https://learn.microsoft.com/en-us/azure/developer/mobile-apps/azure-mobile-apps/quickstarts/winui/
&
https://learn.microsoft.com/en-us/azure/developer/mobile-apps/azure-mobile-apps/howto/data-sync
我遇到的问题是,在快速入门示例中(从这里向上两个链接),Azure数据库是使用发布设置接口在服务依赖项中定义的。该过程设置了一个数据库,本地SQLite DB stor e和client变量可能会自动连接到该数据库。
因为我的数据库名称会有所不同,所以我需要帮助通过下面的DB创建方法中的代码将应用程序连接到正确的Azure数据库,以便正确的Azure数据库将填充新的SQLite数据库。请注意,webjob队列触发器方法中的message参数包含数据库名称,该名称将传递给SQLite DB创建方法。
队列触发器:

public static void ProcessQueue([QueueTrigger("queue_trigger")] string message, ILogger logger)
    {
        try
        {
            if (message.StartsWith("[DB_CREATION]_", StringComparison.OrdinalIgnoreCase))
            {
                message = message.Replace("[DB_CREATION]_", "");

                ProcessSqliteDbCreation(message);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine("Exception in connection establishment: " + ex.Message);
        }
    }

SQLite DB创建方法和支持方法:

private static void ProcessSqliteDbCreation(string azureDBName)
    {
        //Create local dir
        DirectoryInfo di = Directory.CreateDirectory(_DefaultLocalDBPath);

        //get projectdbnameon mobile using projectdbname
        var sqlLiteDBName = GetProjectDbNameOnMobile(azureDBName);

        // Set path of database file
        string DbFile = $"{_DefaultLocalDBPath}{sqlLiteDBName}_{Guid.NewGuid()}.db"; 

        // Create database file
        File.WriteAllBytes(DbFile, new byte[0]);

        string offlineConnectionString = new UriBuilder { Scheme = "file", Path = DbFile, Query = "?mode=rwc" }.Uri.ToString();
        var store = new OfflineSQLiteStore(offlineConnectionString); //"file:" is required

        // Define structure of all tables of database
        DefineTables(store); 

        var options = new DatasyncClientOptions
        {
            HttpPipeline = new DelegatingHandler[] { new DbNameHandler(azureDBName) },
            OfflineStore = store,
            SerializerSettings = new Microsoft.Datasync.Client.Serialization.DatasyncSerializerSettings()
            {
                CamelCasePropertyNames = false,
                DateTimeZoneHandling = DateTimeZoneHandling.Local
            },
        };
        var client = new DatasyncClient(aimWebUtilityUrl, options);

        client.InitializeOfflineStoreAsync();

        // Method for pulling data from Azure DB to new SQLite DB
        KeepPulling(client); //SEE METHOD BELOW

        // Upload created database file on blob storage
        if (File.Exists(DbFile)) CreateAndUploadDbZip(sqlLiteDBName, DbFile);
    }

    public static void KeepPulling(DatasyncClient client)
    {
        ParallelOptions po = new ParallelOptions();
        po.MaxDegreeOfParallelism = 5;
        Parallel.Invoke(po,

            async () => await PullOneAsync<Table1>(client), //SEE METHOD BELOW
            async () => await PullOneAsync<Table2>(client)
            );
    }

    // Pull data from server one by one 
    static async Task PullOneAsync<T>(DatasyncClient client)
    {
        ReadOnlyCollection<TableOperationError> syncErrors = null;

        try
        {
            var table = client.GetOfflineTable<T>();
            table.PullItemsAsync(table.CreateQuery()).Wait(); //ERROR OCCURS HERE (SEE ERROR BELOW)
        }
        catch (PushFailedException exc)
        {
            if (exc.PushResult != null) syncErrors = (ReadOnlyCollection<TableOperationError>)exc.PushResult.Errors;
        }

        // Simple error/conflict handling
        if (syncErrors != null)
        {
            ...
        }
    }

收到的错误如下。该错误发生在pull命令中(请参阅上面代码中的注解),这并不奇怪,因为没有Azure数据库连接。我需要使用提供的数据库名称添加连接。下面列出了错误,以防它在某种程度上有帮助:
System.AggregateException HResult= 0x 80131500消息=发生一个或多个错误。(无法建立SSL连接,请参阅内部异常。)Source=System.Private.CoreLib StackTrace:at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)at System.Threading.Tasks.Task.Wait(Int32毫秒超时,CancellationToken cancellationToken)at System.Threading.Tasks.Task.Wait()at... Functions.d__13 `1.MoveNext()in D:...\Functions.cs:line 580 at... Functions.<>c__DisplayClass12_0. <b__0>d.MoveNext()in D:...\Functions.cs:line 412
内部异常1:HttpRequestException:无法建立SSL连接,请参阅内部异常。
内部异常2:AuthenticationException:身份验证失败,因为远程方发送了TLS警报:'ProtocolVersion'。
内部异常3:Win32异常:收到的消息意外或格式错误。

pzfprimi

pzfprimi1#

当你说 * 我们的Azure数据库之一 * 时,我假设你有server/database1,server/database2。如果是这样,那么使用How to use the ASP.NET Core backend server SDK的后端服务示例,服务依赖性就不是问题。每个数据库都有一个TableController。为了确保Web作业从正确的数据库中提取同步数据,您可以包括表端点,如下所示。

var options = new DatasyncClientOptions
{
    ...
    TableEndpointResolver = (table) => $"/tables/{tableName.ToLowerInvariant()}",
};

主要要点是客户端需要连接到正确的表控制器以同步数据。
但我不认为问题出在代码上,我认为更多的是关于web作业和后端服务器之间的连接。看看DatasyncClient,我会说你的应用服务配置错误。默认情况下,它的底层客户端将"3.0.0"作为ProtocolVersion发送,但内部异常显示它的格式不正确。可能是TLS配置或密码套件问题,很难说。在***诊断和解决问题***刀片中运行***网络跟踪***可以获得更好的信息。

相关问题