Загрузка Curl через Curl API очень медленная - PullRequest
0 голосов
/ 28 июня 2018

Я использую библиотеку CURL для загрузки файла. Мы используем https: // с TLS 1.2. Используется версия Curl 7.48.0. Мы наблюдаем странную проблему. Скручиваемая загрузка работает очень медленно между сервером и клиентом при размере файла 224 МБ. Если мы используем инструмент командной строки curl, это очень быстро, но это не так, если мы вызываем curl_easy_perform со стороны приложения.

Кроме того, мы использовали параметр --libcurl, чтобы проверить разницу между командной строкой и нашим кодом, и ее нет. Мы используем те же параметры, что и в инструменте командной строки, но загрузка происходит очень медленно, когда выполняется прямой вызов curl_easy_perform.

Если мы выполняем загрузку с какого-либо другого сервера и того же клиента, он работает нормально. Однако, только с определенным сервером, мы сталкиваемся с проблемой времени загрузки. Отладка далее, мы обнаружили, что вывод netstat показывает, что очередь приема для сокета tcp очень высока. Однако неясно, почему это может быть проблемой только через нашу программу, а не через командную строку, даже если установлены те же параметры.

1 Ответ

0 голосов
/ 30 июня 2018

Оказалось, что проблема была из-за обратного вызова записи, который занимал время с этим сервером. При обратном вызове записи на прикладном уровне мы сделали malloc, memcpy и бесплатно скопировали полученные новые данные. Это работало нормально со всеми серверами, кроме одного. Разница с соединением с этим сервером заключалась в том, что Curl предоставлял 16378, а затем 6 байтов данных при обратном вызове Write, тогда как на других серверах, где он работает нормально, он всегда выдавал 16384 байта данных. Это то же самое, что размер rmem_max, установленный для буфера сокета по умолчанию на устройстве. Не уверен, почему на конкретном сервере (Wildfly) он разбивается на 16378 байт, за которыми следуют 6 байт. Это приводит к непрерывным циклам malloc, memcpy и свободным циклам для загрузки файла размером 224 МБ. В результате чтение из сокета становится очень медленным, что приводит к медленной загрузке. В инструменте командной строки Curl обратный вызов write записывается по-разному, когда файл открывается, и данные записываются в этот файл, регулярно вызывая fwrite при получении данных, а затем fclose после получения всех данных. Это очень быстрая операция по сравнению с malloc, memcpy и free. Так что инструмент командной строки curl отлично работает для загрузки того же файла. Мы изменили наш обратный вызов write для выравнивания таким же образом, что и командная строка curl, и это решает проблему. Однако причина разделения данных на 16378 + 6 байтов по Curl для этого конкретного сервера не ясна, и я собираюсь исследовать это дальше.

...