3

我正在使用最新的Azure.Data.Tablesnuget 包版本12.3.0连接到 ASP.NET Core C# 应用程序中的 Azure 表存储。

如果主要区域发生故障,我的应用程序需要故障转移到次要区域进行读取。

目前的设置TableServiceClient是在 Startup.cs 中完成的,如下所示:

public void ConfigureServices(IServiceCollection services)
{     
   services.AddSingleton(new TableServiceClient(new Uri("PrimaryRegionConnectionURL"), new DefaultAzureCredential()));
}

如何TableServiceClient使用指向次要区域的实例更新当前实例?是否有更好的方法来实现此故障转移?

澄清一下:我知道客户端不支持故障转移,并且团队已经创建了一张票以在将来查看此功能。我意识到我需要一个新的TableServiceClient.

我只是不确定如何将启动时创建的替换为失败时指向辅助实例的新实例。

这是消耗TableServiceClient

    public class TableRepository : ITableStorageRepository
{
    readonly TableServiceClient _serviceClient;

    public TableRepository(TableServiceClient serviceClient)
    {
        _serviceClient = serviceClient;
    }

    public async Task<ICollection<T>> GetPartitionEntities<T>(string partitionKey, string tableName)
        where T : class, ITableEntity, new()
    {
        var listOfEntities = new List<T>();

        var tableClient = _serviceClient.GetTableClient(tableName);

        var queryResults = tableClient.QueryAsync<T>(filter => filter.PartitionKey == partitionKey);

        await foreach (var row in queryResults) 
        {
            listOfEntities.Add(row);
        }

        return listOfEntities;
    }
}
4

2 回答 2

1

不确定这是否是实现它的最佳方式,但考虑到我必须自己处理在主要和次要端点之间切换的逻辑,我会这样做。

首先,我会创建两个实例TableServiceClient- 一个用于主实例,另一个用于辅助实例。

public void ConfigureServices(IServiceCollection services)
{  
    Dictionary<string, TableServiceClient> tableServiceClients = new Dictionary()
    {
      "Primary",  new TableServiceClient(new Uri("PrimaryRegionConnectionURL"), new DefaultAzureCredential()),
      "Secondary",  new TableServiceClient(new Uri("SecondaryRegionConnectionURL"), new DefaultAzureCredential())
    }
    services.AddSingleton(tableServiceClients);
}

接下来,我将提取用于在单独的函数中获取实体的逻辑并将客户端传递给该函数(我们称之为GetPartitionEntitiesImpl)。

然后在GetPartitionEntities方法中,我会尝试从主要端点获取实体并捕获异常。如果异常表明主端点失败,我会GetPartitionEntitiesImpl再次调用函数并尝试从辅助端点获取实体。

public class TableRepository : ITableStorageRepository
{
    readonly TableServiceClient _primaryServiceClient, _secondaryServiceClient;

    public TableRepository(Dictionary<string, TableServiceClient> tableServiceClients)
    {
        _primaryServiceClient = tableServiceClients["Primary"];
        _secondaryServiceClient = tableServiceClients["Secondary"];
    }

    public async Task<ICollection<T>> GetPartitionEntities<T>(string partitionKey, string tableName)
        where T : class, ITableEntity, new()
    {
        try
        {
            return await GetPartitionEntitiesImpl(_primaryServiceClient, partitionKey, tableName);
        }
        catch (Exception exception)
        {
          //Check if there is a need for failover
          if (shouldTrySecondaryEndpoint)
          {
              return await GetPartitionEntitiesImpl(_secondaryServiceClient, partitionKey, tableName);
          }
        }
    }

    private async Task<ICollection<T>> GetPartitionEntitiesImpl<T>(TableServiceClient serviceClient, string partitionKey, string tableName)
        where T : class, ITableEntity, new()
    {
        var listOfEntities = new List<T>();

        var tableClient = serviceClient.GetTableClient(tableName);

        var queryResults = tableClient.QueryAsync<T>(filter => filter.PartitionKey == partitionKey);

        await foreach (var row in queryResults) 
        {
            listOfEntities.Add(row);
        }

        return listOfEntities;
    }

}

此外,请查看旧版 Azure Storage SDK(版本 9.x)的代码,了解在主端点和辅助端点之间切换的逻辑。该 SDK 可以很好地处理这种情况。

于 2021-12-15T15:26:44.993 回答
0

目前不支持使用同一个客户端的自动故障转移;要使用次要区域,TableServiceClient需要一个单独的区域。此处提供更多上下文:https ://github.com/Azure/azure-sdk-for-net/issues/25456

此处跟踪添加支持的工作:https ://github.com/Azure/azure-sdk-for-net/issues/25710

于 2021-12-15T14:42:24.147 回答