c# - 从 Azure 中托管的 Asp.net Core MVC Web 应用程序获取 "Response status code does not indicate success: 502 (Bad Gateway)"

标签 c# azure asp.net-core-mvc asp.net-core-webapi dotnet-httpclient

我有一个基于 Asp.net core MVC (V 1.1.1) 构建的客户端应用程序和一个基于 Asp.net core (v 2.1) 构建的 Web API。我已将两者托管在 Azure 上。

在发出一些请求时,网络应用程序失败并给出 502 Bad Gateway 响应。

Response status code does not indicate success: 502 (Bad Gateway).

The specified CGI application encountered an error and the server terminated the process.

此问题是间歇性的,但是,当请求的处理时间超过 2 分钟时,似乎会发生此问题。我已在 Web.config 文件中的客户端和 API 端将 requestTimeout 设置为 20 分钟,但仍然没有解决。有时,相同的请求在更短的时间内得到处理,并且我得到了响应。

此外,Httpclient 也设置了 5 分钟超时,但没有成功。

<aspNetCore requestTimeout="00:20:00"/>

_httpClient.Timeout = new TimeSpan(0, 5, 0);

我已经在本地测试了该应用程序,无法面对这个问题,即使处理时间超过 3 分钟也能得到响应。

如果请求超过 2 分钟,Azure Web 应用程序似乎不会等待处理请求。但是, azure session 超时指定为 230 秒(3.8 分钟),但它仍然没有等待,并且应用程序不会将此情况视为错误,也不会记录任何内容。

客户端代码:

public class ApiClientFactory
{
    private static Uri ApiUrl;
    private static Lazy<ApiClient> restClient = new Lazy<ApiClient>(
        () => new ApiClient(ApiUrl),
        LazyThreadSafetyMode.ExecutionAndPublication);

    static ApiClientFactory()
    {
        ApiUrl = new Uri(Convert.ToString(ConfigurationManager.AppSettings["WebAPIUrl"]));
    }

    public static ApiClient Instance
    {
        get
        {
            return restClient.Value;
        }
    }
}
public class ApiClient
{
   private readonly HttpClient _httpClient;
   private readonly Uri BaseEndPointUrl;

   public ApiClient(Uri baseEndPointUrl)
   {
       if (baseEndPointUrl == null)
           throw new ArgumentNullException("baseEndPointUrl");

       BaseEndPointUrl = baseEndPointUrl;
       _httpClient = new HttpClient();
       _httpClient.DefaultRequestHeaders.Add("Accept", "application/json");
       _httpClient.Timeout = new TimeSpan(0, 5, 0); //Timeout needed for few modules to get results from db.
   }

   private HttpContent CreateHttpContent<T>(T content)
   {
       var json = JsonConvert.SerializeObject(content, MicrosoftDateFormatSettings);
       return new StringContent(json, Encoding.UTF8, "application/json");
   }

   private static JsonSerializerSettings MicrosoftDateFormatSettings
   {
       get
       {
           return new JsonSerializerSettings
           {
               DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
           };
       }
   }

   public async Task<T1> PostAsync<T1, T2>(string url, T2 content, string token)
   {
       try
       {
           _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
           var response = await _httpClient.PostAsync(url, CreateHttpContent<T2>(content));

           if (response.StatusCode == HttpStatusCode.InternalServerError){
               var exception = await response.Content.ReadAsStringAsync();
               throw new Exception(exception);
           }
           response.EnsureSuccessStatusCode();
           var data = await response.Content.ReadAsStringAsync();

           return JsonConvert.DeserializeObject<T1>(data);
       }
       catch (Exception ex){throw ex;}
   }
}

请在遇到问题时提供帮助。

最佳答案

您可以实现重试请求的方法,或者简单地使用 .Net Polly对于此类错误。增加超时设置并不是一个好习惯。

方法:

    private async Task<bool> PostAsync()//Params you need
    {
        HttpStatusCode[] httpStatusCodesWorthRetrying =
        {
            HttpStatusCode.RequestTimeout,
            HttpStatusCode.InternalServerError,
            HttpStatusCode.BadGateway,
            HttpStatusCode.ServiceUnavailable,
            HttpStatusCode.GatewayTimeout
        };

        var maxAttempts = 0;

        while (maxAttempts < 3)
        {
            var response =  await _httpClient.PostAsync(requestUrl, CreateHttpContent<T2>(content));
            if (!httpStatusCodesWorthRetrying.Contains(response.StatusCode))
            {
                return true;
            }

            maxAttempts ++;
            await Task.Delay(300);
        }
        return false;
    }

波莉:

    private async Task PostAsync()//Params you need
    {
        HttpStatusCode[] httpStatusCodesWorthRetrying =
        {
            HttpStatusCode.RequestTimeout,
            HttpStatusCode.InternalServerError,
            HttpStatusCode.BadGateway,
            HttpStatusCode.ServiceUnavailable,
            HttpStatusCode.GatewayTimeout
        };


        _retryPolicy = Policy
            .Handle<HttpRequestException>()
            .OrResult<HttpResponseMessage>(r => httpStatusCodesWorthRetrying.Contains(r.StatusCode))
            .WaitAndRetry(4, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));

        _retryPolicy.Execute(await _httpClient.PostAsync(requestUrl, CreateHttpContent<T2>(content)));

    }

关于c# - 从 Azure 中托管的 Asp.net Core MVC Web 应用程序获取 "Response status code does not indicate success: 502 (Bad Gateway)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59702119/

相关文章:

c# - 隐藏元素与 DataTriggers

c# - 如何增加表达到的数量?

node.js - 从 Azure Function (Node.JS) 设置项目的 TimeToLive

c# - 具有 MVC6 依赖项注入(inject)的 EF7 构造函数

c# - 在 MVC 程序中调用 Web API

c# - 为什么我不能将记录插入到我的 SQL Compact 3.5 数据库中?

c# - 如何获取用户的ID以查看模型? [登录表单]

azure - 如何在 Azure 中获取电源状态正在运行且特定标记为空的 VM 的 ID?

c# - 如何以通过 AAD 进行身份验证的 ASP.NET MVC 站点中的登录用户身份查询 Dynamics 365 CRM?

c# - Asp.net vNext 中的 Thread.Sleep