繁体   English   中英

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

[英]Parallel HttpClient calls throwing 500 internal server error

我需要实现对 API 的并行调用。

这很奇怪,因为如果我有 3 个请求,2 个传递给外部 api,第三个失败(错误 500)。 如果我留下 2 个请求,第一次我收到两个请求的成功消息 200 OK。如果我转到另一个链接或刷新我的浏览器,结果两次调用抛出异常错误 500。

有时两次调用第一次运行工作正常,下次抛出异常。 如果我有 3 个请求,第一个和第二个返回 200 OK,第三个抛出异常消息。

我尝试了两种并行方法,但我觉得 HttpClient 有一些限制。 我怎样才能解决这个问题 ? 在一次调用中解析 get 数组结果是行不通的,因为我无法更改外部 api 方法。

这些是方法:

    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 提前致谢。

这不是HttpClient的问题。 根据文档GetAsync 是线程安全的。

您必须在服务器上调试代码或从服务器获取完整的错误消息,因为这是您调用的 API 的问题。

暂无
暂无

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

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