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

Практический пример с Wireshark

const express = require('express');
const app = express();
app.post('/save', async (req, res) => {
    //await new Promise((resolve) => setTimeout(resolve, 60000)) // Set time for 1 Minute
    res.send('Job Done');
});
app.listen(8191);

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

После запуска сервера и отправки первого запроса из Insomnia давайте рассмотрим Wireshark. Здесь, как видно из первых трех строк, мы видим, что начальное соединение установлено (3-стороннее рукопожатие).

В качестве дополнительных столбцов добавлены столбцы «Дельта-время» и «Расчетный размер окна». Термин «размер окна» просто относится к максимальному размеру приемного буфера. Размер буфера приема клиента или размер буфера приема сервера, в зависимости от того, клиент это или сервер. Размер окна исходного запроса составляет 65535. Но в строке номер 39 размер окна составляет 2619648.

В строке 40 это маршрут от клиента к серверу. В нем указано, что размер окна равен 10233. Если мы получим первый размер окна, он отобразит 65535. Эти 65535 байт не очень велики. Что делать, если загружается или загружается файл размером 2 ГБ? Представьте, что вы отправляете 65535 байт, получаете ACK, затем снова отправляете 65535 байт, получаете ACK и так далее. Загрузка заняла бы целую вечность. Таким образом, он движется довольно медленно.

Когда мы пытались обрабатывать большие файлы, протокол или расширение сети заставляли нас хотеть иметь больше места. Чтобы это исправить, они добавили в меню настроек флаг под названием «Масштаб окна». Шкала окна означает 8, это ²⁸, что равно 256. Это означает, что даже если наша сделка рассчитана на 256 раз, я готов принять это как 65535.

Если вы исследуете пакет, например, строку 40 в Wireshark. Параметр «Масштаб окна» отсутствует. Учитывая, что это просто происходит во время рукопожатия. Чтобы правильно проанализировать нашу медлительность, мы должны перехватить пакеты SYN SYN-ACK ACK. Потому что мы должны обеспечить максимальное использование пропускной способности.

Давайте попробуем загрузить большой файл и посмотрим, что произойдет.

Загружаемый файл имеет размер 412,2 килобайта. Нормальное трехстороннее рукопожатие произошло в первых трех строках после того, как мы загрузили файл, нажав кнопку «Отправить». Однако размер окна с 41 по 48 строку быстро меняется. Опять же, в строке 49 мы достигаем очень важного значения 10232.

Сервер открывается для определенного размера окна, пока мы работаем с измеренным размером окна буфера. Например, когда сервер указывает, что он имеет размер 100, клиент отправляет на сервер данные размера 100. В настоящее время на сервере их 100. Однако на сервере в этом экземпляре запущено другое приложение. Приложение перекачивает данные Клиенту, а Клиент отправляет их Серверу, поскольку Сервер — это всего лишь протокол и приложение на уровне 7. Поэтому программа сервера извлекает их из буфера. когда клиент отправляет 100 на сервер, а сервер отвечает ACK. В настоящее время приложение, которое сейчас выполняется на сервере, использует 90 байт из буфера. Осталось всего 10. Чтобы сохранить размер буфера, сервер может еще раз запросить у клиента значение 90. В этот момент клиент передает 90, а серверное приложение использует 70. Опять же, сервер запрашивает у клиента значение 70. Таким образом, ясно, что это падает.

Далее принять = Полный размер (-) Остаться в буфере

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

Вы должны решить эту проблему, если заметите, что ваша система зависает и нет оконных пакетов.

Если мы внимательно изучим трехэтапное рукопожатие в первых трех строках, ответы столбца Delta Time или RTT приходят примерно через миллисекунды. Если есть задержка, мы должны это проверить. Столько времени нам нужно, чтобы передать пакет на сервер и вернуться с сервера. Следовательно, каждое рукопожатие занимает эту продолжительность. Если сервер передает 100 байт с SYN равным 1, проблема заключается в следующем. Прежде чем данные окажутся в буфере отправки сервера, клиент должен подтвердить ACK 101 байт, что соответствует количеству времени, необходимому серверу для очистки буфера отправки. Если сервер вяло реагирует, что указывает на то, что ACK приходит медленно, серверу потребуется сохранить дополнительные данные в буфере отправки даже после того, как они были отправлены. Из-за полного буфера передачи сервер не может принимать новые данные. Передача в настоящее время медленнее.

Повторная передача TCP — это термин, используемый для описания этого. Возьмем предыдущий экземпляр. Сервер отправил 100 байт, однако Клиент не подтвердил запрос сервера. Поэтому Сервер держит. Когда происходит тайм-аут сервера, но клиент отправляет ACK на сервер, сервер еще раз отправляет клиенту те же SEQ и ACK. Если соединение медленное, вы увидите, что сервер отправляет клиенту несколько повторных передач.

Спасибо за чтение! Если вам понравилось, ставьте аплодисменты и подписывайтесь на мою страницу.

Кишара Буддика