Azure 表存储 - 调用超时/永不从 Azure WebApp (Linux) 上运行的 .NET 5 WebAPI 返回

问题描述

在我们的代码中遇到一个问题,并希望找到解决它或更好地调试情况的方法

我们有一个 .NET 5 WebAPI 项目,我们将其部署到运行 Linux 的 Azure WebApp。

我们有两个“组件”可以访问 Azure 表存储:

  1. 查询包装到表存储中的存储库类
  2. Orleans IClusterClient,它使用 Table Storage 进行集群配置(即客户端的 Build()ing 将检查 Table Storage 以获取与 Silo 的连接详细信息)

我们已设置 DI 以将包装器注入 IClusterClient 和 API 控制器使用的通用 TableRepository<>

首先,这是我们为连接到奥尔良所做的工作:

var clientBuilder = new ClientBuilder()
    .Configure<ClusterOptions>(options =>
    {
        options.ClusterId = "clusterId";
        options.ServiceId = "serviceId";
    })
    .UseAzureStorageClustering(opts => opts.ConnectionString = "table_cnn_string");

var client = clientBuilder.Build(); // <-- this never returns,or times out

就在我们调用 clientBuilder.Build() 时,该调用没有回来。它可能在 120(或 180?)秒后超时。

通过 Microsoft.Azure.Cosmos.Table nuget 包(最新版本 - 1.0.8)与 Table Storage 交互的此代码(Orleans 客户端)和其他代码都存在相同的问题。

这段代码

var client = CloudStorageAccount.Parse("cnn_str").CreateCloudTableClient();
var cloudTable = client.GetTableReference("ATable");
if (!await cloudTable.ExistsAsync()) // <-- never returns or times out after 120 seconds
{
    await cloudTable.CreateIfNotExistsAsync();
}

在我们调用 cloudTable.ExistsAsync()(或非异步变体)时,我们要么永远不会返回,要么在 120 秒后超时(我绝对能够跟踪超时)。

真的很挣扎,因为当我在我的 Windows 10 开发盒上本地运行它时,一切正常 100%。

我的场景是:

  • 在本地从 VS 2022 运行 WebAPI,一切正常
  • 通过 WSL 2 从 VS 2022 运行 WebAPI,一切都按预期运行
  • 部署到 Azure WebApp,观察是这些调用永远不会返回(但可能在 120 秒左右后超时)

例如,我们有一个用于监控的状态 API 端点,如下所示:

[ApiController]
public class StatusController : ControllerBase
{
    private readonly ILogger<StatusController> _logger;
    private readonly IClusterClient _clusterClient;


    public StatusController(ILogger<StatusController> logger,IClusterClient clusterClient)
    {
        _logger = logger;
        _clusterClient = clusterClient;
    }

    [HttpGet]
    public async Task<ActionResult<ApiStatusCheck>> GetStatus()
    {
        // ... bunch of other checks

        try
        {
            _logger.Loginformation("SILO CHECK");

            // there is no async version of this
            var checkGrain = await _clusterClient.GetGrain<IStatusCheck>(1); //<-- never returns
            _logger.Loginformation("SILO CHECK: got grain");
            details = await checkGrain.GetStatus();
            _logger.Loginformation($"SILO CHECK: got: {details}");
        }
        catch (Exception ex)
        {
            details = ex.Message;
        }
   
        // ... more checks,then return a response
    }

因为除了 Azure WebApp 之外,我无法在其他任何地方重新创建它,而且我无法(据我所知)通过调试器连接到它(由于它在 Linux 上运行),我很难理解:

  • 为什么会这样
  • 为什么它在本地有效,但在部署时无效
  • 如何真正诊断问题
  • 修复它(以某种方式)

奇怪的是,访问 Azure Blob 存储可以正常工作。

另外,重要的是,我不能放弃使用 Orleans 客户端,并且由于它内部依赖于 Microsoft.Azure.Cosmos.Table,因此简单地切换到其他一些 API 是不可能的(目前)。

感谢任何帮助。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)