从 Azure 中托管的 ASP.NET Core 5.0 MVC 站点调用 API/服务时出现间歇性套接字异常

问题描述 投票:0回答:3

Application Insights 中的错误消息:

由于连接方在一段时间后没有正确响应而导致连接尝试失败,或者由于连接的主机未能响应而建立连接失败。 (OurApiUrlAddress:443) 连接尝试失败,因为连接方在一段时间后没有正确响应,或者由于连接的主机未能响应而建立的连接失败。

始终是 21 秒的 TCP 超时,这是我知道的一个非常普遍的错误,但此错误的原因并不总是相同,我一直在阅读有关此问题的所有线程。我们已经调查这个问题几个月了,但没有成功,我们也在与 Azure 团队联系。

重要:用 RUBY 编写的同一个站点过去使用相同的 API,没有任何问题,该 API 是响应式的,从其他站点调用它也没有任何问题,但这个特定站点已从 RUBY 迁移到 .NET,并在同时该网站托管在 AZURE 中,这是两个重大变化。当站点(记住它托管在 Azure 中)调用我们公司托管的 API/服务时,就会发生这种情况,当站点调用其他地方托管的服务时,不会发生这种情况,这些使我们认为问题可能与公司基础设施有关但这不可能是单独的,这必须以某种方式与 .NET 和 AZURE 有关,因为这些 API 和服务可以完美地响应来自我们网络中托管的其他站点的调用,并且它们与该站点的 ruby 版本配合良好。从公司网络外部在浏览器中调用时,这些 API 和服务不会抛出此错误。

服务/API 位于防火墙后面,但端口配置完美(没有任何其他流量应用程序或设备在起作用)。

这个错误不是似乎与端口耗尽或SNAT有关,因为有时只有1个开发人员单独在DEV环境中工作,他会收到此套接字异常错误。

仅供参考,我们在生产环境中每天会收到大约 250 个套接字异常,而这只是所有调用的一小部分,因此有时会发生某些事情。

我们知道创建多个实例时存在众所周知的 HttpClient 问题,因此我们决定使用 Singleton 方法,确保每个 API/服务只有 1 个实例,正如我将在此处展示的,这是会产生更多套接字异常的调用:

StartUp
类/文件中:

services.AddSingleton<IUploadApi>(new UploadApi(new HttpClient() { BaseAddress = new Uri(appSettings.Endpoints.UploadServicesUrl) }));

appsettings.json
的一部分:

"Endpoints": {
    "UploadServicesUrl": "https://ourApiUrlAddress"
},

UploadApi.cs

public interface IUploadApi
{
    Task<UploadArtworkViewModel.UploadConfigurationData> GetUploadConfiguration();
}

public class UploadApi : IUploadApi
{
    private readonly HttpClient httpClient;

    public UploadApi(HttpClient client)
    {
        httpClient = client;
    }

    public async Task<UploadArtworkViewModel.UploadConfigurationData> GetUploadConfiguration()
    {
        var response = await httpClient.GetAsync("api/GetUploadConfiguration").ConfigureAwait(false);
        var json = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

        return JsonConvert.DeserializeObject<UploadArtworkViewModel.UploadConfigurationData>(json);
    }
}

来自控制器的呼叫:

model.UploadConfiguration = await UploadApi.GetUploadConfiguration().ConfigureAwait(false);

欢迎任何关于要测试的东西或要查看的地方的想法,显然我无法重现这个。我们知道总会有 21 秒的超时,这是 TCP 超时,但这并没有多大帮助。也许由于某种原因连接被断开或者 Azure 在访问公司网络时(有时)出现问题。如果需要,我可以发布来自应用程序见解的更多信息,但我没有看到有关该错误的任何特别信息。

编辑 - 更多信息:当从此 MVC 站点控制器调用任何 API 或服务时,就会发生这种情况,因此当站点服务器尝试访问 API 或服务时,问题会偶尔出现(仍然是每天 300 次),这使得我相信这与公司基础设施有关,但仍然不知道它可能是什么。

asp.net-mvc azure asp.net-core .net-5
3个回答
0
投票

来自 asp.net 怪物:

“应用程序已退出,但仍然有一堆这样的 连接打开”

“它们处于 TIME_WAIT 状态,这意味着连接已 一侧(我们的)已关闭,但我们仍在等待是否有 额外的数据包进入其中,因为它们可能已被延迟 在网络上的某个地方。”

即使您使用单例 HttpClient,似乎某些连接正在等待其他包,这会导致套接字耗尽。

解决方案是更改代码并使用 HttpClientFactory 或 HttpClientFacotoryLite。使用 HttpClientFactory 的原因是生成 HttpClient 实例,这些实例从套接字处理程序池中重新使用套接字处理程序。处理程序会定期回收以处理 DNS 更改。总之,当使用 HttpClientFactory 时,HttpClient 将工作委托给 SocketClientHandler。


0
投票

我们与 Azure 团队合作一段时间后终于解决了这个问题,这是一个网关问题,解决方案是应用 NAT/Vnet 集成。这就是我们修复它的方法: https://learn.microsoft.com/en-us/azure/app-service/networking/nat-gateway-integration


0
投票

您知道造成这种情况的根本原因是什么吗? 我们最近遇到了完全相同的问题,通过设置出站 NAT 网关解决了这个问题。我们仍然不知道是什么原因造成的?

© www.soinside.com 2019 - 2024. All rights reserved.