Как измерить производительность сети (как проверить сетевой протокол)

Сначала немного фона. Существует множество различных сравнений распределенных систем контроля версий (DVCS), которые сравнивают размер репозитория или скорость тестирования операций. Я не нашел ни одного, который бы оценивал производительность сети различных DVCS, а также различные используемые протоколы... помимо измерения скорости операций (команд), связанных с сетью типа "clone", "pull" /'fetch "или" push ".

Я хотел бы узнать, как бы вы сделали такое сравнение; как измерять производительность сети приложения или как оценивать сетевой протокол. Я представляю здесь, среди прочих, также измерение зависимости производительности и пропускной способности сети и времени ожидания (времени пинга) сети; некоторые протоколы жертвуют латентностью в форме более круглых обменов (переговоров), чтобы отправить минимально необходимый окончательный "пакет".

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

Предпочитаемая ОС: Linux
Предпочтительные языки: C, Perl, shell script


Возможные измерения:

  • общее количество байтов, переданных от сервера к клиенту и от клиента к серверу за один сеанс; это также может использоваться для измерения служебных данных протокола (полосы пропускания).
  • количество раундов (соединений) в одной транзакции (латентность)
  • зависимость скорости работы сети (время, затрачиваемое на клонирование/вытягивание/нажатие) от полосы пропускания сети и от задержек сети (время пинга)

Как сделать такие измерения (такие тесты)?


Добавлено 02-06-2009:
Простейшим эталоном (измерение) будет сетевая версия команды time, т.е. Команда, которая запускает, дает мне количество переданных байтов и количество округленных поездок/сетевых соединений во время выполнения данной команды.


Добавлено 09-06-2009:
Пример мнимого выхода для упомянутого выше решения сетевой версии команды time может выглядеть следующим образом:

$ ntime git clone -q git://git.example.com/repo.git
...
bytes sent: nnn (nn kiB), bytes received: nnn (nn kiB), avg: nn.nn KB/s
nn reads, nn writes

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


Добавлено 09-06-2009:
Похоже, что некоторые из того, что я хочу, можно получить, используя dummynet, инструмент (изначально) для тестирования сетевых протоколов...

Ответ 1

Если я правильно понимаю вас, вы в основном заинтересованы в чем-то вроде Linux 'strace' (Введение) для сетевых системных вызовов?

Возможно, комбинация профилировщика и отладчика для сетевых приложений (т.е. "ntrace" ), предоставляя подробный анализ различных необязательных измерений?

В Linux утилита strace в основном основана на функциональности, предоставляемой ядром Linux, а именно ptrace (трассировка процесса) API:

Используя ptrace, вы можете получить большую часть интересующих вас данных.

В Windows вы, вероятно, захотите изучить detours, чтобы перехватывать/перенаправлять вызовы API Winsock для целей проверки/сопоставления.

Если вам действительно не нужна вся эта информация с низким уровнем низкого уровня, вы, возможно, также можете напрямую использовать strace (в linux) и использовать ее только для отслеживания определенных системных вызовов, например, рассмотрите следующую строку, которая будет отслеживать только вызовы открытый syscall (используя дополнительный параметр -o FILE, вы можете перенаправить весь вывод в выходной файл):

strace -e trace=open -o results.log

Передавая дополнительный флаг -v в strace, вы можете увеличить его многословие, чтобы получить дополнительную информацию (при работе с SCM, например git, которые состоят из множества небольших утилит оболочки и автономных инструментов, вы, вероятно, также захотите посмотрите на использование флага -f, чтобы также следовать forked-процессам).

Итак, что вам было бы интересно, это все системные вызовы, связанные с сокетами, а именно:

  • принять
  • bind
  • connect
  • getpeername
  • getsockname
  • getsockopt
  • прослушать
  • recv
  • recvfrom
  • отправить
  • sendto
  • setsockopt
  • shutdown
  • розетка
  • socketpair

(в начале вы, вероятно, только захотите изучить проблемы с отправкой... /recv...),

Чтобы упростить это, вы также можете использовать "сеть" в качестве параметра для трассировки, который будет отслеживать все вызовы, связанные с сетью:

-e trace = network: отслеживать все системные вызовы, связанные с сетью.

Итак, соответствующий вызов strace может выглядеть так:

strace -v -e trace=accept,bind,connect,getpeername,getsockname,getsockopt,listen,recv,recvfrom,send,sendto setsockopt,shutdown,socket,socketpair -o results.log -f git pull

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

Например, при запуске в оболочке linux: strace -v -o wget.log -e trace=connect,recv,recvfrom,send,sendto wget http://www.google.com

В результате файл журнала содержит такие сообщения:

  • recv (3, "HTTP/1.0 302 Найдено \r\nLocation: htt"..., 511, MSG_PEEK) = 511
  • sendto (4, "\ 24\0\0\0\26\0\1\3 ^\206 * J\0\0\0\0\0\0\0\0"..., 20, 0, {sa_family = AF_NETLINK, pid = 0, groups = 00000000}, 12) = 20

Глядя на страницы руководства для этих двух системных вызовов, очевидно, что 511 и соответственно 20 - это количество передаваемых байтов. Если вам также нужна подробная информация о времени, вы можете передать флаг -T в strace:

-T - время печати, затрачиваемое на каждый syscall

Кроме того, вы можете получить некоторую статистику, передав флаг -c:

-c: подсчитывать время, вызовы и ошибки для каждого системного вызова и сообщать сводную информацию о программе Выход. В Linux это пытается показать системное время (время работы процессора в ядре) независимо от времени настенных часов. Если -c используется с -f или -F (ниже), только совокупность итоговые значения для всех отслеживаемых процессов сохраняются.

Если вам также необходимо изучить фактические обработанные данные, вам может понадобиться изучить спецификаторы чтения/записи:

-e read = set: выполнить полный шестнадцатеричный и ASCII дамп всех данных, считанных из файла дескрипторы, перечисленные в указанном наборе. Например, чтобы увидеть всю активность ввода в файле дескрипторы 3 и 5 используют -e read = 3,5. Обратите внимание, что это не зависит от нормального отслеживание системного вызова read (2), который контролируется опцией -e trace = read. -e write = set: выполнить полный шестнадцатеричный и ASCII дамп всех данных, записанных в файл дескрипторы, перечисленные в указанном наборе. Например, чтобы увидеть всю активность вывода в файле дескрипторы 3 и 5 используют -e write = 3,5. Обратите внимание, что это не зависит от нормального отслеживание системного вызова write (2), который управляется опцией -e trace = write.

Вы также можете настроить максимальную длину строк:

-s strsize: укажите максимальный размер строки для печати (по умолчанию 32). Обратите внимание, что имена файлов не считаются строками и всегда печатаются полностью

Или нужно сбросить строки как hex:

-xx: печать всех строк в шестнадцатеричном формате строки.

Таким образом, использование strace для большей части этого, похоже, является хорошим гибридным подходом, потому что его очень легко сделать, но при этом имеется достаточное количество информации о низком уровне, если вы обнаружите, что вам нужна дополнительная информация о низком уровне, вы можете рассмотреть возможность расширения strace или подачи соответствующих запросов функций с помощью проекта strace на sourceforge.

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

Довольно похожий на прокси-сервер (например, SOCKS), так что весь трафик туннелируется через ваш анализатор, который, в свою очередь, может накапливаться статистики и других показателей.

Базовая версия чего-то вроде этого, вероятно, может быть легко скомбинирована только с помощью сценариев netcat и некоторых оболочек, однако более сложные версии могут извлечь выгоду из использования perl или python.

Для реализации сервера SOCKS на python вы можете посмотреть pysocks.

Кроме того, конечно, twisted для python:

Twisted - это механизм, управляемый событиями, написанный на Python и лицензируется по лицензии MIT.

Если вам нужна информация более низкого уровня, вы, вероятно, действительно захотите изучить перехватывание системных вызовов.

Если вам также нужны данные эффективности эффективности протокола, вы можете посмотреть tcpdump.

Ответ 2

Возможным ответом было бы использовать SystemTap. Среди примеров сценариев есть nettop, который отображает (некоторые из) требуемую сетевую информацию в стиле "сверху", и есть iotime script, который показывает информацию ввода/вывода в требуемой форме.