Введение в знание TCP об архитектуре с высокой степенью параллелизма

Архитектура TCP/IP

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

Эта статья не просто расскажет вам о трехстороннем рукопожатии TCP и четырех взмахах рук. Если это так, я просто опубликую несколько ссылок и все. Я надеюсь, что многие моменты в реальной работе можно связать воедино и рассказать всем. Конечно, чтобы закончить статью, я все же начну стрехстороннее рукопожатиеначало.

Поговорим о процессе изменения состояния TCP

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

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

трехстороннее рукопожатие

Давайте посмотрим на картинку трехстороннего рукопожатия. Предполагается, что все будут рвать, когда они смотрят на эту картину, но почему они не могут вспомнить каждый раз, когда они интервью и вспоминают? Я скопирую этот горшок с остатками снова!

tcp-1st

Сначала, когда сервер находится вlistenКогда состояние находится в состоянии, мы можем инициировать мониторинг на стороне клиента, в это время клиентская сторона будет в состоянии.SYN_SENTгосударство. Когда сервер получит это сообщение, он вернетSYNи в то же времяACKЗапрос клиента, то сервер будет вSYN_RCVDгосударство. На этот раз клиент получает на стороне сервераSYN&ACK, он отправит на серверACK, затем вESTABLISHEDгосударство. Сервер получил свойACKтакже будет вESTABLISHEDгосударство.

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

Прежде всего, поговорим о 4-х рукопожатиях, на самом деле, для обеспечения надежности количество рукопожатий можно повторять вечно, но без завершения это бессмысленно. Итак, 3 раза достаточно, чтобы убедиться, что есть входящие и исходящие сообщения со всех сторон. Конечно, здесь может быть ситуация, что клиент отправляетACKпотерялся в сети. Что делать тогда?

  1. На самом деле, большую часть времени мы отправим данные сразу после установления соединения, поэтому, если сервер не получает егоACKНеважно, когда данные будут получены, соединение будет считаться установленным;
  2. Если данные не передаются сразу после установления соединения, сервер будет периодически пересылать соединение, если соединение не установлено успешно.SYN&ACKпока клиент не подтвердит успех.

Кроме того, почему не два рукопожатия? Двустороннее рукопожатие мы можем представить, что в конце нет трехэтапного рукопожатия.ACKНа практике это происходит, что клиент отправляетACKЕсли сервер не получает его (случай 1 выше), означает ли это, что два рукопожатия также возможны? Посмотрите на второй случай, двустороннее рукопожатие. Когда сервер отправляет сообщение, считается, что установление прошло успешно, и бывает, что в это время передачи данных нет. Это создает ситуацию растраты ресурсов. Например, клиент может отправить несколько соединений из-за задержки.Когда сервер получает ответ на запрос, он считает, что соединение установлено успешно, но многие из этих запросов являются повторными соединениями, вызванными задержками, что приводит к потере большого количества драгоценного ресурса.

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

Далее давайте посмотрим на реальную ситуацию, перехватив пакеты, как описано выше.

20:33:26.583598 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [S], seq 621839080, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1050275400 ecr 0,sackOK,eol], length 0
20:33:26.660754 IP 103.235.46.39.80 > 192.168.0.102.58165: Flags [S.], seq 1754967387, ack 621839081, win 8192, options [mss 1452,nop,wscale 5,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,sackOK,eol], length 0
20:33:26.660819 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [.], ack 1754967388, win 4096, length 0

Захват пакетов: sudo tcpdump -n host www.baidu.com -S

  • SУказывает СИН
  • .Указывает на подтверждение
  • PУказывает на передачу данных
  • FПлавник

помахал четыре раза

Помашите рукой, значит передача данных окончена, до свидания товарищи!

tcp-3th

Здесь есть проблема, на которую нужно обратить внимание, ведь и клиент, и сервер могут активно инициировать операцию выключения.close()Просто сначала отправьте конец запроса. Конечно, в общем процессе партия, которая инициирует соединение, будет инициировать тесный запрос (по адресу http).

По поводу процесса махания 4 раза объяснять не буду.Здесь два важных состояния.Объяснить нужно,это ошибка онлайн которую я испытал лично.close_waitиtime_wait.

Дайте команду, статистика tcp различных состояний. Вот оглавление из статистики этой команды.

netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'

TCP-состояние количество подключений
CLOSE_WAIT 505
ESTABLISHED 808
TIME_WAIT 3481
SYN_SENT 1
SYN_RECV 1
LAST_ACK 2
FIN_WAIT2 2
FIN_WAIT1 1

Много CLOSE_WAITЭто в моем предыдущем постеАнализ причин большого количества CLOSE_WAIT онлайнБыло введено, что это приведет к тому, что большое количество сокетов не будет освобождено. И каждый сокет — это файл, который будет занимать ресурсы. Эта проблема в основном связана с кодом. Появляется на стороне пассивного выключения (раньше называлась серверной).

много TIME_WAITЭта проблема часто встречается в повседневной жизни, и большое количество таких ситуаций возникает, как только трафик становится высоким. Это состояние возникает на стороне, которая инициирует завершение работы. Как правило, время ожидания для этого состояния устанавливается равным 2MSL, а затем автоматически отключается.MSL — это максимальное время жизни сегмента, максимальное время жизни сообщения., если пакет превышает это время, он будет отброшен. Сокеты в этом состоянии не могут быть переработаны. Я столкнулся с такой ситуацией в сети, каждый раз, когда есть большой трафик, сокеты каждой машины в этом состоянии достигают 10w+, что намного больше.Establishedсостояние сокета и все больше и больше, что часто приводит к снижению скорости отклика службы. С одной стороны, вы можете настроить обработку параметров ядра, с другой стороны, чтобы избежать использования слишком большого количества коротких ссылок, вы можете использовать пул соединений для повышения производительности. Также на уровне кода это может быть связано с тем, что в некоторых местах не закрывается соединительный провод, но также необходимо проверить бизнес-код.

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

Наконец, вот данные захвата пакета при вейве:

20:33:26.750607 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [F.], seq 621839159, ack 1754967720, win 4096, length 0
20:33:26.827472 IP 103.235.46.39.80 > 192.168.0.102.58165: Flags [.], ack 621839160, win 776, length 0
20:33:26.827677 IP 103.235.46.39.80 > 192.168.0.102.58165: Flags [F.], seq 1754967720, ack 621839160, win 776, length 0
20:33:26.827729 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [.], ack 1754967721, win 4096, length 0

Не больше, не меньше, ровно в 4 раза.

изменение состояния TCP

В сети есть картинка конечного автомата TCP.Я думаю она слишком сложная.Сделаю по-своему простой и понятной. Я объясняю изменение состояния с двух точек зрения.

  • один клиент
  • Один это сервер

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

Изменение состояния клиента

tcp-4th

По этой картинке можно четко узнать изменения TCP на клиенте?

изменение состояния сервера

tcp-5th

Эта картинка описывает переход состояния TCP на стороне сервера.

Управление потоком TCP и контроль перегрузки

Мы часто говорим, что TCP - ориентирован на соединение, UDP является соединением. Так что это TCP-ориентированное в основном, чтобы решить проблему?

Здесь продолжайте размещать данные захвата пакетов трехэтапного рукопожатия для анализа:

20:33:26.583598 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [S], seq 621839080, win 65535, options [mss 1460,nop,wscale 6,nop,nop,TS val 1050275400 ecr 0,sackOK,eol], length 0
20:33:26.660754 IP 103.235.46.39.80 > 192.168.0.102.58165: Flags [S.], seq 1754967387, ack 621839081, win 8192, options [mss 1452,nop,wscale 5,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,nop,sackOK,eol], length 0
20:33:26.660819 IP 192.168.0.102.58165 > 103.235.46.39.80: Flags [.], ack 1754967388, win 4096, length 0

Выше мы сказалиTCPНаиболее важной частью трехэтапного рукопожатия является согласование порядкового номера, используемого для передачи данных. Так какая польза от этого серийного номера? Этот порядковый номер может помочь двум последующим концам подтвердить, получен ли пакет данных, и решить проблему последовательности и потери пакетов; кроме того, мы также можем видеть, что существуетwinполе, которое является размером окна для связи между двумя сторонами, которое также переносится во время каждой передачи данных. Главное, сказать другой стороне, что мое окно такое большое, не постить слишком много или не постить слишком мало.

Подводя итог, можно выделить несколько характеристик TCP:

  • Проблема последовательности, основанная на порядковых номерах
  • Проблема пакета потерь, полагается на серийный номер
  • Управление трафиком, опираясь на скользящее окно
  • Контроль перегрузки, основанный на окне перегрузки + скользящее окно
  • Техническое обслуживание, трехстороннее рукопожатие / из четырехсторонней волны

Проблемы с последовательностью и потерей пакетов

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

Поскольку каждый из наших пакетов имеет порядковые номера, хотя передача и прибытие могут быть непоследовательными, уровень TCP можно переупорядочить в соответствии с порядковым номером; в таком расположении он имеет 1, 2, 3, 5 6. Эти пакеты , одна проверка, знаю 4 либо задержка не достигнута, либо потеряете пакет, ждите возврата.

Здесь важно отметить вот что. Для повышения эффективности TCP фактически не отправляет подтверждение после получения пакета. Как это подтверждено? Продолжая приведенный выше пример, TCP получает пакеты 1, 2, 3, 5 и 6 и может отправитьack ,seq=3, так что 3 пакета подтверждаются одновременно. Но он не отправляет подтверждение для 5,6. Потому что 4 не получили ах! Как только приходит задержка 4 или поступает повторная передача,ack, seq=6, опять подтвердили 3 пакета.

Контроль трафика и контроль заторов

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

Сначала поговорим об этом:

  • Управление потоком: оно основано на размере окна получателя, чтобы понять, сколько данных я могу передать другой стороне на этот раз; —— Скользящее окно
  • Контроль перегрузки: Хотя контроль перегрузки в основном предназначен для предотвращения перегрузки сети, он учитывает больше проблем. В зависимости от комплексных факторов, сколько данных отправить другой стороне; — Скользящее окно и окно перегрузки

Например, например: A отправляет данные B. После рукопожатия A знает, что B может получить 1000 данных за раз (у B такая большая вычислительная мощность), тогда скользящее окно может быть установлено на 1000 в это время. Действительно ли возможно отправить так много данных на B в конце концов? Еще нет, в это время нужно спросить окно перегрузки, мужик, как сейчас ситуация с сетью? Утомительно ли отправлять 1000 данных за раз? Окно перегрузки рассчитывается так, чтобы сказать «нет», сейчас пиковый период, и в пути может находиться не более 600 товаров. В конце концов, когда данные передаются на этот раз, это метка 600. Также можно обратить внимание на данные захвата пакетовwinзначение, которое было динамически скорректировано.

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

Таким образом, для того, сколько данных может быть отправлено каждый раз, существует такая формула:

LastByteSend - LastByteAcked <= min{cwnd,rwnd}

  • LastByteSend — порядковый номер последнего отправленного байта.
  • LastByteAcked Порядковый номер последнего подтвержденного байта

Данные, полученные путем вычитания двух, — это данные, которые можно отправить на этот раз.Эти данные должны быть меньше или равны наименьшему значению cwnd и rwnd. Я верю, что все могут понять.

Какова же роль этой части знания? Руководящее значение заключается в том, что если ваш бизнес очень важен, очень важно сделать микс; когда мы обслуживаем дизайн услуги, на него очень ссылаются. Это что-то вроде очереди сообщений? (Многие очереди сообщений одинаковы, можем ли мы добавить концепцию окна для оптимизации?)

что ограничивает ваше соединение

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

tcp-6th

Предположим, мой серверNginx, позвольте мне попытаться интерпретировать его. когда клиент звонитconnect()В это время будет инициировано трехстороннее рукопожатие.Во время этого рукопожатия есть несколько элементов, которые однозначно определяют эту коммуникацию (или этот сокет),[Исходный IP-адрес: исходный порт, целевой IP-адрес: целевой порт], конечно, этот сокет не используется для передачи данных.После завершения рукопожатия сервер вернетsocketОн используется исключительно для последующей передачи данных. Здесь давайте вызовем первый сокетслушать сокет, второй позвонилтранспортная розеткаЭто удобно описать позже.

Почему он разработан таким образом? Подумайте об этом, если прослушивающий сокет также отвечает за отправку и получение данных, как можно повысить эффективность этого сервера? Бросать что угодно и всех в эту розетку слишком сложно!

Улучшить процедуры подключения

На этом этапе давайте остановимся и посчитаем, сколько подключений может иметь наш сервер? Как можно шаг за шагом преодолеть этот предел?

во-первыхслушать сокет, прот сервера вообще фиксированный, и айпи сервера естественно фиксированный (автономный). Тогда приведенная выше структура[Исходный IP-адрес: исходный порт, целевой IP-адрес: целевой порт]По сути можно изменить только ip и порт клиента. Предполагая, что клиент использует IPv4, теоретическое количество подключений: 2^32 (количество ips) * 2^16 (количество портов) = 2^48.

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

Так как же помириться? Известные мне операции: многопроцессорность, многопоточность, мультиплексирование ввода-вывода, сопрограммы и другие средства используются в комбинации.

мультипрогресс

Это процесс, который слушает, однажды приняв, длятранспортная розеткаМы создадим новый дочерний процесс, с которым будем иметь дело. Но и в этом случае разветвление процесса, процесс разрушения особенно хлопотен. Создание единого верхнего предела процесса ограничено.

Многопоточность

Поток намного легче, чем процесс.Он разделяет многие ресурсы родительского процесса, такие как файловые дескрипторы и пространство процесса.У него просто есть еще одна ссылка. Так легче создавать и разрушать. Каждыйтранспортная розеткаЗдесь он передается потоку для обработки.

Но есть проблема, многопроцессный он или многопоточный, одно соединение соответствует одному процессу или сопрограмме. Трудно убежатьC10KПроблема. Что же тогда делать?

мультиплексирование ввода-вывода

Мультиплексирование ввода/вывода Что это значит? В приведенной выше простой многопроцессорной многопоточной модели процесс или поток может обрабатывать только одно соединение. После использования мультиплексирования ввода-вывода процесс или поток I смогут обрабатывать несколько соединений.

мы все знаемNginxОчень эффективный, его структура: мастер + рабочий, рабочий порт будет прослушивать запросы до 80 443. Обычно он устанавливается на количество рабочих ядер процессора, тогда такой маленький дочерний процесс, как решить его через несколько подключений? На самом деле, каждый рабочий здесь на использовании модели epoll (мультиплексирование ввода-вывода, конечно, есть выбор, здесь не могу сказать).

Рабочий процесс в состоянии прослушивания отправит всеслушать сокетДобавьте в свой собственный epoll. Когда все эти сокеты находятся в epoll, если в сокете происходит событие, он будет немедленно разбужен обратным вызовом (это касается красно-черного дерева epoll, подробно объяснить не понятно). Этот режим значительно увеличивает количество сокетов, которыми может управлять каждый процесс, а верхний предел может быть напрямую повышен до максимального дескриптора файла, с которым может работать процесс.

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

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

О ulimit

В конце статьи добавьте несколько автономных настроек дескриптора файлов. Мы часто говорим, что количество подключений ограничено файлами дескрипторов, почему?

Поскольку в Linux все является файлом, каждый сокет рассматривается как файл, и каждый файл будет иметь файловый дескриптор. В linux у каждого процесса есть массив, содержащий все файловые дескрипторы, необходимые процессу. Этот дескриптор файла на самом деле является этим массивомkey,этоvalueЭто указатель, указывающий на соответствующий открытый файл.

В отношении файловых дескрипторов следует отметить две вещи:

  1. Соответствует файлу на linux
  2. Значение самого файлового дескриптора может повторяться в разных процессах.

Кроме того, добавлено, что онлайн-лимит ulimit, установленный одной машиной, ограничен и двумя конфигурациями системы:

fs.nr_open, уровень процесса

fs.file-max, системный уровень

fs.nr_open всегда должен быть меньше или равен fs.file-max Установка этих двух значений не является произвольной, потому что чем больше параметр, тем больше потребление системных ресурсов, поэтому его необходимо установить в соответствии с реальная ситуация.


至此,本篇长文就完结了。 Это то же самое, что и предыдущийВведение в знания CDN об архитектуре с высокой степенью параллелизмаАрхитектуры с высокой степенью параллелизма, принадлежащие к серии, должны понимать основы работы в сети.

О знании HTTP/HTTPS тоже напишу позже. Тогда все, что связано с сетью с высокой степенью параллелизма, закончилось. Я начну следующую главу.