Как гласит заголовок: я извлекаю данные из API через программу C # (в данном случае API Shopify).Прежде всего, API Shopify получил следующее ограничение: он использует алгоритм leaky bucket для обработки входящих запросов, где его размер корзины равен 40 запросам , а скорость утечка 2 запроса в секунду .Таким образом, если корзина заполнена и новый запрос попадает в API, сам API ответит сообщением об ошибке HTTP 429 (слишком много запросов) . Вы можете проверить больше об этом в документации Shopify: https://help.shopify.com/en/api/getting-started/api-call-limit.
Я извлекаю некоторые данные из Shopify, нажимая на их API, и на самом деле объем данных немного (например, 80-90k)транзакций заказа), но из-за ограничений API довольно сложно достичь этого за минимально возможное время.Таким образом, в основном то, что делает моя программа, - это 40 вызовов API-интерфейса Shopify, я жду их, затем засыпаю программу на пару секунд (10 секунд) и выполняю следующие 40 вызовов.Из-за того, что я нажимаю следующий пакет, не дожидаясь соответствующего времени, чтобы избежать ответов HTTP 429, я реализовал шаблон повторных попыток для повторных HTTP-вызовов, которые не выполняются из-за некоторой временной ошибки (например, HTTP 429, 503 и т. Д.), Поэтому я 'я стараюсь изо всех сил стараться не получать частичные результаты.
Так вот, что делает моя программа; Я вытащил 85 000 транзакций за 11 часов (что, по-моему, довольно плохо), но я пытаюсь выяснить, где еще можно улучшить, чтобы сократить время обработки.Я знаю, что в API Shopify есть узкое место, но это не входит в мои задачи ... Как вы думаете, ребята, есть какой-то метод / подход для улучшения извлечения данных из API?Я хотел бы услышать ваши мнения / мысли по этому поводу.Я полностью открыт для любых предложений!Кроме того, я был бы очень благодарен.
Проверьте фрагмент кода ниже, чтобы увидеть одну из функций моей программы, которая показывает логику, объясненную выше.Я также хотел бы поблагодарить любой обзор кода;Например, достаточно ли производительности, предлагаемой методом AsParallel
из класса ParallelEnumerable
, для ситуации, с которой я работаю?
public void BulkInsertOrdersEvents(List<long> orders, IPersistence persistence)
{
if (orders != null && orders.Any())
{
return;
}
short ordersPerBurst = 40;
int totalOrders = orders.Count;
int ordersProcessed = 0;
while (true)
{
if (ordersProcessed >= totalOrders)
{
break;
}
var ordersForProcess = orders.Skip(ordersProcessed).Take(ordersPerBurst);
var orderEventsBag = new ConcurrentBag<string>();
ordersForProcess.AsParallel().ForAll((orderId) =>
{
var httpCallParameters = new Dictionary<string, object>();
httpCallParameters.Add("orderId", orderId);
Console.WriteLine("Started processing the order {0}", orderId);
int pages = CalculatePages(ShopifyEntity.OrderEvent, httpCallParameters);
if (pages == 0)
{
return;
}
string getOrderEventsEndpoint = string.Format(ShopifyApiEndpoints.GET_ORDER_EVENTS_BY_ORDER_ID, orderId) + $"?limit=250"; ;
Parallel.For(1, pages + 1, (index) =>
{
//Create HTTP client for call Shopify API
var httpClient = GetHttpClient();
var httpHeaders = GetHttpHeaders();
//Call Shopify API for return order transactions
string orderEvents = httpClient.Get(getOrderEventsEndpoint + "&page=" + index, httpHeaders);
Console.WriteLine("Obtained page {0} of Events from Order {1}", index, orderId);
//Put the order's events for current page into concurrent bag
orderEventsBag.Add(orderEvents);
});
Console.WriteLine("Finished processing the order {0}", orderId);
});
Dictionary<string, object> saveParameters = null;
if (persistence.GetType().Name.Equals(typeof(BlobPersistence).Name))
{
string fileName = string.Format(ShopifyApiConstants.ORDER_EVENTS_FILE_NAME_TEMPLATE, DateTime.UtcNow.ToString("yyyyMMddHHmmss"));
saveParameters = new Dictionary<string, object>()
{
{"fileName", fileName}
};
}
//Merge all events pages into a single JSON and store it.
var orderEventsJson = JsonHelper.MergeJsons(orderEventsBag.ToArray());
persistence.Save(orderEventsJson, saveParameters);
Thread.Sleep(TimeSpan.FromSeconds(5));
ordersProcessed += ordersPerBurst;
}
}
Я упустил упомянуть, что я также сохраняю эти результаты наХранилище BLOB-объектов Azure;но это совсем не проблема!Там, где моя программа отнимает так много времени, это получение данных из Shopify.
Большое спасибо, ребята!