批处理请求产生System.IO.IOException:打开的文件太多

时间:2019-06-13 06:36:11

标签: ubuntu nginx asp.net-core hangfire

我们有一个使用dotnet core 2.2的API应用程序,该应用程序使用nginx部署在ubuntu服务器中,该服务器对第3方api进行批量请求。我们不确定请求背后到底发生了什么,但是我们的自定义记录器指出了使用hangfire的批处理模块中发生的异常。

发生的事情是,批处理将通过任务执行多个请求,并且当作业失败时,无论何时我们向API提出请求,都会使整个应用程序崩溃,并出现502网关超时状态错误。

代码

FetchPrices

        try
        {
            var tasks = new List<Task<Price>>
            {
                //BTC
                Task.Run(async () => { return await GetPrice(CurrencyType.USD, CryptoCurrencyType.BTC); }),
                Task.Run(async () => { return await GetPrice(CurrencyType.EUR, CryptoCurrencyType.BTC); }),
                Task.Run(async () => { return await GetPrice(CurrencyType.JPY, CryptoCurrencyType.BTC); }),
                Task.Run(async () => { return await GetPrice(CurrencyType.CNY, CryptoCurrencyType.BTC); }),

                //ETH
                Task.Run(async () => { return await GetPrice(CurrencyType.USD, CryptoCurrencyType.ETH); }),
                Task.Run(async () => { return await GetPrice(CurrencyType.EUR, CryptoCurrencyType.ETH); }),
                Task.Run(async () => { return await GetPrice(CurrencyType.JPY, CryptoCurrencyType.ETH); }),
                Task.Run(async () => { return await GetPrice(CurrencyType.CNY, CryptoCurrencyType.ETH); }),
            };

            var results = await Task.WhenAll(tasks);
            using (var transaction = _priceRepository.BeginTransaction())
            {
                   Saving to DB
            }
        }
        catch (Exception e)
        {
             //The exception from GetPrice will be logged here
            _logger.WriteLogs(_appSettings.AssetRootPath, _appSettings.LogFilePrefix, "Batch", "AggregateExchange", null, e.Message, e.StackTrace, null);
        }

GetPrice函数

        var tasks = new List<Task<PriceDetails>>();
        var ticker = new Ticker();
        var currencyStr = Enum.GetName(typeof(CurrencyType), type);

        var btcStr = Enum.GetName(typeof(CryptoCurrencyType), CryptoCurrencyType.BTC);
        var ethStr = Enum.GetName(typeof(CryptoCurrencyType), CryptoCurrencyType.ETH);

        var currency = c_type == CryptoCurrencyType.BTC ? $"{btcStr}-{currencyStr}" : c_type == CryptoCurrencyType.ETH ? $"{ethStr}-{currencyStr}" : $"{bceStr}-{currencyStr}";

        tasks.Add(Task.Run(async () => { return await GetPriceDetails(currency, PriceType.Spot); }));

        if (c_type != CryptoCurrencyType.BCE)
        {
            tasks.Add(Task.Run(async () => { return await GetPriceDetails(currency, PriceType.Sell); }));
            tasks.Add(Task.Run(async () => { return await GetPriceDetails(currency, PriceType.Buy); }));
        }


        var results = await Task.WhenAll(tasks); //An error occurs here

GetPriceDetails函数

        var JsonObj = string.Empty;
        var partialUrl = string.Empty;

        if (type == PriceType.Buy)
        {
            partialUrl = string.Format(_appSettings.BuyPriceApi, currency);
        }
        else if (type == PriceType.Sell)
        {
            partialUrl = string.Format(_appSettings.SellPriceApi, currency);
        }
        else
        {
            partialUrl = string.Format(_appSettings.SpotPriceApi, currency);
        }

        JsonObj = await _apiRequest.SendCoinbaseRequest(
               HttpMethod.Get,
               _appSettings.CoinbaseRoot,
               partialUrl,
               _appSettings.ApiKey,
               _appSettings.ApiSecret
               );

        var res = JsonConvert.DeserializeObject<PriceReceiver>(JsonObj);
        return res.Data;

是否需要考虑任何可能导致服务器超时的输入?

我们要做的是再次重建并重新发布api,但是它再次发生。我们认为该函数的catch方法中的throw异常行是导致API崩溃的那一行,但是即使将其删除,它仍然会崩溃。

这是实际的例外情况。

System.IO.IOException
Too many open files

System.IO.IOException: Too many open files
   at Infrastructure.Base.ErrorLogger.WriteLogs(String rootPath, String filePrefix, String controller, String action, String request, String exceptionType, String logErrorMessage, String jwtToken) in /home/exchange/exchange-api/staging/bigcatman-api/BOE.Core/Infrastructure/Base/ErrorLogger.cs:line 48
   at Service.Batch.Implementation.AggregateExchange.FetchPrices() in /home/exchange/exchange-api/staging/bigcatman-api/BOE.Core/Service/Batch/Implementation/AggregateExchange.cs:line 179
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

0 个答案:

没有答案