简体   繁体   English

并行 HttpClient 调用引发 500 内部服务器错误

[英]Parallel HttpClient calls throwing 500 internal server error

I need to implement parallel calls to API.我需要实现对 API 的并行调用。

It's weird because If I have 3 requests, 2 passed to external api and third failed (Error 500).这很奇怪,因为如果我有 3 个请求,2 个传递给外部 api,第三个失败(错误 500)。 If I leave 2 requests, first time I get success message 200 OK for a both requests.If I go to another link or refresh my browser and result with two calls throw exception error 500.如果我留下 2 个请求,第一次我收到两个请求的成功消息 200 OK。如果我转到另一个链接或刷新我的浏览器,结果两次调用抛出异常错误 500。

Sometimes with two call first running works OK and next time throw exception.有时两次调用第一次运行工作正常,下次抛出异常。 If I have 3 requests, first and second return 200 OK and third throw exception message.如果我有 3 个请求,第一个和第二个返回 200 OK,第三个抛出异常消息。

I was trying with two paraellel approach but I feel the HttpClient has some limit.我尝试了两种并行方法,但我觉得 HttpClient 有一些限制。 How can I fix this ?我怎样才能解决这个问题 ? Resolving for the get array results in one call won't do because I can not change external api methods.在一次调用中解析 get 数组结果是行不通的,因为我无法更改外部 api 方法。

These are methods:这些是方法:

    private async Task<IEnumerable<PaymentDetailsResponseDto>> GetPaymentDetails(CancellationToken cancellationToken)
    {
            try
            {
                    var paymentDetailsResponse = new List<PaymentDetailsResponseDto>();
                    var cardInfo = new List<CardResponseDto>();                                  
                    long[] paymentIds = { 2, 3};

                   //  // PARALLEL REQUESTS WITH BACTHES //
                    var batchSize = 100;
                    int numberOfBatches = (int)Math.Ceiling((double)paymentIds.Count() / batchSize);

                    for (int i = 0; i < numberOfBatches; i++)
                    {
                        var currentIds = paymentIds.Skip(i * batchSize).Take(batchSize);
                        var tasks = paymentIds.Select(id => _paymentsService.GetCardInfo(id, cancellationToken));
                        cardInfo.AddRange(await Task.WhenAll(tasks));
                    }

                     // PARALLEL REQUESTS //
                    //var tasks = paymentIds.Select(id => _paymentsService.GetCardInfo(id, cancellationToken));
                    //var results = await Task.WhenAll(tasks);

                    paymentDetailsResponse = cardInfo.Select(x => new PaymentDetailsResponseDto
                    {
                        CardNumber = x.CardNumber,
                        ExpirationDate = x.ExpirationDate,
                        CardSecurityCode = x.CardSecurityCode,
                        Amount = x.Amount,
                        Address = BILLING_ADDRESS,
                        City = BILLING_CITY,
                        State = BILLING_STATE,
                        Zip = BILLING_ZIP
                    }).ToList();

                return paymentDetailsResponse;             
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"Error duriduring getting card info.");
                throw;
            }
    } 

    public async Task<VirtualCardResponseDto> GetCardInfo(long? paymentId, string virtualCardId, CancellationToken cancellationToken)
    {                    
                try
                {
                    var response = await _client.GetAsync(string.Format(/api/payments/card-info/?paymentId={0}, paymentId, cancellationToken));

                    response.EnsureSuccessStatusCode();

                    var result = await response.Content.ReadAsStringAsync();
                    if (!string.IsNullOrEmpty(result))
                    {
                        return JsonSerializer.Deserialize<CardResponseDto>(result, new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
                    }

                    throw new Exception($"An error occurred while getting data in Payment Service, Status Code {response.StatusCode.ToString()}");
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "Error occurred in Payment Service client during getting card info.");
                    throw;
                }
    }

    [HttpGet("card-info")]
    public async Task<ActionResult<CardResponseDto>> GetCardInfo(long paymentId,  CancellationToken cancellationToken)
    {
        return Ok(await _paymentManager.GetCardInfoAsync(paymentId, cancellationToken));
    }

错误消息仅指示错误 500 Thanks in advance.提前致谢。

It is not a problem with HttpClient .这不是HttpClient的问题。 According to the documentation GetAsync is thread safe.根据文档GetAsync 是线程安全的。

You have to debug the code on the server or obtain the full error message from the server because it's a problem with the API you are calling.您必须在服务器上调试代码或从服务器获取完整的错误消息,因为这是您调用的 API 的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM