2017-01-11 16 views
0

В нашем онлайн-проекте на основе C/S мы используем TCP для сетевой передачи. Мы включаем Libevent, автоматически используем буферизацию для каждого подключения к обработке с помощью сетевого ввода-вывода.Чрезвычайно высокая латентность при занятости сети, TCP, libevent

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

  • средняя загрузка процессора снизилась (0% -60% -0% -60% повтор, ожидая что-то?)
  • чистый трафик уменьшился (nethogs)
  • клиенты, подключенные к серверу еще живой (NetStat & TCPDUMP)

Это выглядит как-то волшебным образом замедлили всю систему вниз, но новое подключение к серверу откликнулся выйти вовремя.

Когда я изменил протокол на UDP, он работает хорошо в той же ситуации: нет очевидной задержки, система работает быстро. Чистый трафик составляет около 3 Мбит/с.

Проект работает в Интранете. Я также тестировал максимальную скорость загрузки, почти 18M/S.

Я изучил часть файлов заголовков и дубликатов Libevent, попытался установить ограничение скорости для всех подключений. Он сделал некоторые улучшения, но не полностью разрешил проблему, хотя я пробовал несколько разных конфигураций. Вот мои параметры: read_rate 163840, read_burst 163840, write_rate 163840, write_burst 163840, tick_len 500ms.

Благодарим за помощь!

ответ

1

TCP = Протокол управления передачей. Он реагирует на потерю пакетов путем повторной передачи неподтвержденных пакетов после задержки. В случае повторных потерь он будет экспоненциально отступать. Посмотрите на этой сеть захвате попытки открыть подключение к узлу, который не отвечает:

enter image description here

Он посылает начальный SYN, а затем, после получения не ПДТОВ для 1s он пытается снова. После того, как вы не получите ack, он отправит другой после ~ 2s, затем ~ 4s, затем ~ 8s и т. Д. Таким образом, вы можете видеть, что вы можете получить некоторую серьезную задержку в результате повторной потери пакетов.

Поскольку вы сказали, что сознательно подчеркиваете сеть, и что использование ЦП является непоследовательным, одно из возможных объяснений заключается в том, что TCP ждет повторной передачи потерянных пакетов.

Лучший способ увидеть, что происходит, это получить сетевой захват того, что на самом деле передано. Если ваши хосты подключены к одному коммутатору, вы можете «проложить» порт интереса к порту другого хоста, где вы можете сделать захват.

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

Я предлагаю установить wirehark для анализа захвата сети (что вы можете делать в режиме реального времени, используя wirehark для выполнения захвата). Каждый раз, когда вы работаете с сетевой системой, я бы рекомендовал использовать wirehark, чтобы у вас была определенная информация о том, что на самом деле происходит в сети. Первый фильтр, который я предлагаю вам использовать, - tcp.analysis.flags, который покажет вам пакеты, наводящие на размышления о проблемах.

Я бы также предложил отключить ограничение скорости, чтобы попытаться посмотреть, что происходит (ограничение скорости добавляет еще причине не отправлять пакеты, что, вероятно, затруднит диагностику происходящего). Кроме того, 500 мс могут быть длинными tick_len в зависимости от того, как работает ваша игра. Если ваша пакетная конфигурация позволяет использовать скорость в 100 мс, вы сможете дождаться 400 мс, прежде чем сможете снова передать ее. В этом отношении диаграмма ввода-вывода является очень полезной функцией Wireshark. Это может помочь вам увидеть скорость передачи, хотя интервал и единица измерения по умолчанию не очень полезны в этом отношении. Ниже приведен пример пульсирующей скорости потока ограничивается 200mbit/с:

enter image description here

Обратите внимание, что интервал клеща 1 мс, и блок бит/тик, что делает верхнюю часть диаграммы 1gb/с , скорость интерфейса, о которой идет речь.

+0

Я очень благодарен вам за вашу помощь, большое вам спасибо! Я последовал вашим советам, чтобы получить сетевой захват через wirehark. Я получил в общей сложности 312788 кадров в течение 180 секунд, в том числе: 37 Дублировать ACK от клиента к серверу, 27 повторных передач с сервера на клиент. График ввода-вывода также очень непоследовательный, в основном 94 Кбайт/с, и внезапно взлетает до 4040 ~ 5586 КБ/с в течение обычного временного интервала. Средний временной интервал составляет около 7 секунд, и с течением времени интервал становится все длиннее и длиннее, другими словами, график ввода-вывода становится все более непоследовательным. – walter

+0

@walter Добро пожаловать. Если вы можете поместить захват где-нибудь, я могу его получить, я был бы рад взглянуть. Возможность выяснить, что происходит от сетевого захвата, - это настоящий навык, который, как правило, хорош в использовании отладчика. Но это может быть очень ценный навык, который стоит инвестировать. –

+0

Могу ли я получить ваш адрес электронной почты? Мне немного сложно загрузить файл в облачный сервис, который вы можете легко получить. Скорость здесь, чтобы просмотреть зарубежный сайт, очень медленная. – walter