Как улучшить производительность FtpWebRequest? - PullRequest
34 голосов
/ 19 июня 2009

У меня есть приложение, написанное на .NET 3.5, которое использует FTP для загрузки / выгрузки файлов с сервера. Приложение работает нормально, но есть проблемы с производительностью:

  1. Требуется много времени для подключения к FTP-серверу. FTP-сервер находится в другой сети и имеет Windows 2003 Server (IIS FTP). Когда несколько файлов ставятся в очередь для загрузки, переход из одного файла в другой создает новое соединение с использованием FTPWebRequest, и это занимает много времени (около 8-10 секунд).

  2. Возможно ли повторно использовать соединение? Я не очень уверен насчет свойства KeepAlive. Какие соединения поддерживаются и используются повторно.

  3. IIS-FTP в Windows Server 2003 не поддерживает SSL, поэтому любой может легко увидеть имя пользователя / пароль через анализатор пакетов, например WireShark. Я обнаружил, что Windows Server 2008 поддерживает SSL через FTP в своей новой версии, если IIS 7.0.

Я хочу улучшить производительность загрузки / выгрузки моего приложения. Любые идеи будут оценены.

** Обратите внимание, что 3 не проблема, но я хотел бы, чтобы у людей были комментарии к ней

Ответы [ 18 ]

38 голосов
/ 23 июня 2010

Я провел несколько экспериментов (загрузил около 20 файлов разного размера) в FtpWebRequest со следующими факторами

KeepAlive = true / false

ftpRequest.KeepAlive = isKeepAlive;

Имя группы соединения = Пользовательский или ноль

ftpRequest.ConnectionGroupName = "MyGroupName";

Предел подключения = 2 (по умолчанию) или 4 или 8

ftpRequest.ServicePoint.ConnectionLimit = ConnectionLimit;

Режим = Синхронный или Асинхронный

см. этот пример

Мои результаты:

  1. Использовать ConnectionGroupName, KeepAlive = true (21188,62 мс)

  2. Использовать ConnectionGroupName, KeepAlive = false взял (53449,00 мсек)

  3. Нет ConnectionGroupName, KeepAlive = false заняло (40335,17 мсек)

  4. Использовать ConnectionGroupName, KeepAlive = true; async = true, подключение = 2 заняло (11576,84 мс)

  5. Использовать ConnectionGroupName, KeepAlive = true; async = true, подключение = 4 заняло (10572.56 мс)

  6. Использовать ConnectionGroupName, KeepAlive = true; async = true, подключение = 8 заняло (10598,76 мс)

Выводы

  1. FtpWebRequest предназначен для поддержки внутреннего пула соединений. Чтобы убедиться, что пул соединений используется, мы должны убедиться, что ConnectionGroupName устанавливается.

  2. Установка соединения стоит дорого. Если мы подключаемся к одному и тому же ftp-серверу с использованием тех же учетных данных, то для флага keep alive установите значение true, чтобы минимизировать количество установленных подключений.

  3. Рекомендуется асинхронный способ, если у вас много файлов для ftp.

  4. Количество подключений по умолчанию - 2. В моей среде ограничение числа подключений в 4 даст мне наибольшее увеличение производительности. Увеличение количества соединений может или не может улучшить производительность. Я бы порекомендовал, чтобы в качестве параметра конфигурации было установлено ограничение на число подключений, чтобы вы могли настроить этот параметр в своей среде.

Надеюсь, вы найдете это полезным.

18 голосов
/ 25 июня 2009

Неважно, если отдельные соединения занимают много времени, если вы можете запустить много параллельно. Если у вас есть много элементов для передачи (скажем, сотни), то имеет смысл запускать десятки и даже сотни веб-запросов параллельно, используя асинхронные методы, такие как BeginGetRequestStream и BeginGetResponse . Я работал над проектами, которые сталкивались с подобными проблемами (длительное время соединения / аутентификации), но при параллельном выполнении множества вызовов общая пропускная способность была действительно очень хорошей.

Также очень важно, если вы используете асинхронные методы или синхронные методы, как только у вас будет много (десятки, сотни) запросов. Это относится не только к вашим методам WebRequests, но и к вашим методам Stream read / write , которые вы будете использовать после получения потока загрузки / выгрузки. Книга «Повышение производительности и масштабируемости .Net». книга немного устарела, но многие ее рекомендации остаются в силе, и ее можно свободно читать в Интернете.

Следует учитывать, что класс ServicePointManager скрывается в Framwework с единственной целью: подорвать вашу производительность. Убедитесь, что вы получили ServicePoint вашего URL-адреса и изменили ConnectionLimit на разумное значение (по крайней мере столько, сколько число одновременных запросов вы намереваетесь).

5 голосов
/ 29 июня 2009

Отладочная сеть

Несколько хитростей для простой сетевой отладки:

  1. Проверьте время отклика при пинге FTP-сервера с сервера приложений.
  2. Проверьте время отклика для маршрута трассировки (tracert из оболочки DOS).
  3. Передача файла из командной строки с помощью команды ftp.
  4. Подключение к FTP-серверу через Telnet: telnet server 21.

Результаты позволят решить проблему.

Сетевое оборудование

Для медленного маршрута трассировки:

  • Определите, почему на двух компьютерах возникают проблемы с сетью.
  • Обновите сетевое оборудование между самыми медленными линиями.

Конфигурация сети

Для медленного пинга:

  • Проверьте конфигурацию сети на каждом компьютере.
  • Убедитесь, что настройки оптимальны.

Проверка API

Медленный сеанс FTP из командной строки скажет вам, что проблема не изолирована от используемого вами API-интерфейса FTP. Это не исключает API как потенциальную проблему, но, безусловно, делает его менее вероятным.

Ошибки сети

Если пакеты отбрасываются между источником и адресатом, ping сообщит вам. Возможно, вам придется увеличить размер пакета до 1500 байт, чтобы увидеть какие-либо ошибки.

Сервер очереди FTP

Если у вас нет контроля над целевым FTP-сервером, пусть промежуточный сервер получает загруженные файлы. Затем посредник отправляет файлы на удаленный сервер с любой возможной скоростью. Это создает иллюзию того, что файлы отправляются быстро. Однако, если файлы должны существовать на удаленном сервере сразу после их загрузки, это решение может оказаться нежизнеспособным.

Программное обеспечение FTP-сервера

Используйте другой демон FTP на FTP-сервере, например ProFTPd в качестве службы Windows . (ProFTPd имеет плагины для различных баз данных, которые позволяют аутентификацию с использованием SQL-запросов.)

Операционная система FTP-сервера

Операционная система на основе Unix может быть лучшим вариантом, чем основанная на Microsoft.

Программное обеспечение FTP-клиента

Существует несколько различных API для отправки и получения файлов по FTP. Может потребоваться некоторая работа, чтобы сделать ваше приложение достаточно модульным, чтобы вы могли просто подключить новую службу передачи файлов. Несколько разных API перечислены здесь как ответы.

Альтернативный протокол

Если FTP не является обязательным требованием, попробуйте:

  • сетевой диск Windows
  • HTTPS
  • scp, rsync или аналогичные программы ( Cygwin может потребоваться)
4 голосов
/ 13 октября 2010

Эта ссылка описывает влияния ConnectionGroupName и KeepAlive: WebRequest ConnectionGroupName

3 голосов
/ 23 июня 2009

Вы обязательно должны проверить БИТЫ , что является большим улучшением по сравнению с FTP. Пароли в виде открытого текста - не единственная слабость FTP. Существует также проблема предсказания порта, который он откроет для пассивной загрузки или загрузки, и просто общая сложность, когда клиенты используют NAT или брандмауэры.

BITS работает через HTTP / HTTPS с использованием расширений IIS и поддерживает загрузку и загрузку по очереди, которые можно запланировать с низким приоритетом. В целом он намного более гибкий, чем FTP, если вы используете Windows на клиенте и сервере.

БИТЫ для PowerShell

БИТЫ для .NET

2 голосов
/ 28 июня 2009

Посмотрите на эту страницу - http://www.ietf.org/rfc/rfc959.txt

В нем говорится об использовании другого порта при подключении для возможности повторного использования соединения.
Это работает?

2 голосов
/ 15 января 2010

Я настоятельно рекомендую Компонент Starksoft FTP / FTPS для .NET и Mono . У него есть объект подключения, который вы можете кэшировать и использовать повторно.

2 голосов
/ 22 июня 2009

Лично я перенес все наши приложения с использования FTP для загрузки / выгрузки файлов и вместо этого развернул решение на основе веб-служб XML в ASP.NET.

Производительность значительно улучшена, безопасность настолько низка, насколько вы хотите кодировать (и вы можете использовать встроенные в .NET вещи), и все это может пройти через SSL без проблем.

Наш показатель успешности получения подключений наших клиентов через собственные брандмауэры на порядок лучше, чем при использовании FTP.

1 голос
/ 04 августа 2012

Чтобы решить проблему с производительностью, вам просто нужно установить:

ftpRequest.ConnectionGroupName = "MyGroupName"; ftpRequest.KeepAlive = false; ftpRequest.ServicePoint.CloseConnectionGroup("MyGroupName");

1 голос
/ 21 сентября 2013

Я знаю, что это старая ветка, но недавно мне пришлось пройти через аналогичную ситуацию.

Нам нужно было загрузить более 70 XML-файлов с ftp-сервера менее чем за 25 минут, не открывая более 5 соединений в течение этого периода времени.

Это были все альтернативы, которые мы попробовали:

  • wget - это было быстро, но каждый GET означал новое соединение. Нам пришлось остановиться из-за количества созданных соединений. У нас были некоторые проблемы с GETM, которые хорошо документированы в Интернете, поэтому это было невозможно.
  • FtpWebRequest - Каждый вызов Create будет регистрировать новое соединение, даже если мы использовали свойства KeepAlive и ConnectionGroupName. Плюс это было очень медленно.
  • Webclient - мы не проверяли, создавало ли оно новое соединение для каждого файла (хотя я предполагаю, что это так), но оно копировало 1 файл / минуту. Так что это был не вариант.

В итоге мы использовали старомодный пакетный скрипт ftp. Это быстро, и я использую только одно соединение, чтобы загрузить все файлы. Это не гибко, но гораздо быстрее, чем все, что я пробовал (75 файлов за 20 минут).

...