Открывает ли TCP новое соединение для каждого отправленного пакета?

Это может быть глупый вопрос, но я и несколько приятелей обсуждали потенциальные ограничения TCP. У нас есть приложение, которое будет слушать клиентов (думать о шлюзе) и направлять все подключенные данные клиентов через одного подключенного издателя кафки к одной теме.

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

Я занимался разработкой в ​​течение нескольких лет и никогда не слышал об этом раньше, и хотел бы получить более глубокое понимание (как я думал, я имел) о том, как работает TCP. Я понимаю, что когда вы устанавливаете TCP-соединение, это соединение остается открытым до тех пор, пока приложение не закроется или не будет принудительно закрыто ни сервером, ни клиентом. Данные, передаваемые по этому соединению, представляют собой поток и не будут открывать /закрывать новые соединения независимо от 3 V (объем, скорость, сорт).

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

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

12 голосов | спросил user0000001 13 MarpmTue, 13 Mar 2018 21:31:03 +03002018-03-13T21:31:03+03:0009 2018, 21:31:03

8 ответов


19
  

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

Твой друг плохо запутался. TCP - это протокол, ориентированный на поток. В нем нет понятия сообщений. Конечно, он использует пакеты на уровне IP, но для приложения это деталь реализации. TCP вставляет границы пакетов, где имеет смысл это сделать, и не обязательно один раз за write () или send () . Аналогично, он объединяет последовательные пакеты вместе, если вы получаете более одного вызова между read () или recv () .

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

(На практике большинство протоколов, построенных поверх TCP, имеют нечто похожее на сообщения, такие как HTTP-запросы и ответы, но TCP не знает и не заботится о структурах таких вещей.)

Возможно, ваш друг думал о UDP, у которого есть сообщения, но также недоступен. Большинство реализаций сокетов позволяют «подключать» UDP-сокет к удаленному хосту, но это всего лишь удобный способ избежать неоднократного указания IP-адреса и порта. На самом деле он ничего не делает на сетевом уровне. Тем не менее, вы можете вручную отслеживать, с какими пэрами вы разговариваете под UDP. Но если вы это сделаете, тогда решение о том, что считается «соединением», является вашей проблемой, а не ОС. Если вы хотите восстановить «соединение» для каждого сообщения, вы можете это сделать. Это, вероятно, не очень хорошая идея.

ответил Kevin 13 MarpmTue, 13 Mar 2018 22:38:17 +03002018-03-13T22:38:17+03:0010 2018, 22:38:17
7
  

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

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

  

Данные, передаваемые по этому соединению, являются потоком и не будут открываться /   закрыть новые соединения независимо от 3 В (объем, скорость,   выбор).

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

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

ответил Ron Maupin 13 MarpmTue, 13 Mar 2018 21:40:01 +03002018-03-13T21:40:01+03:0009 2018, 21:40:01
5

Нет, TCP не требуется , чтобы открыть новое соединение для каждого отправленного пакета.

Вы можете отправить несколько пакетов с помощью постоянных соединений HTTP , где:

  

... одно TCP-соединение для отправки и приема нескольких HTTP-запросов /ответов [используется], в отличие от открытия нового соединения для каждой отдельной пары «запрос /ответ».

Прикрепленное изображение представляет собой разницу между несколькими соединениями (многие соединения, установленные для отправки одного объекта на одно соединение) и постоянное соединение (одно соединение установлено и несколько отправленных в нем объектов):

 Несколько соединений против постоянного соединения

Источник: https://www.vcloudnine.de /как к драматически-улучшить-сайт-нагрузки раза /

ответил orbuculum 13 MarpmTue, 13 Mar 2018 21:50:21 +03002018-03-13T21:50:21+03:0009 2018, 21:50:21
4

Ваша интерпретация TCP работает правильно.

Что касается вашего друга, я вижу здесь две возможности:

  1. Вы неправильно поняли своего друга, который ссылался на некоторое ограничение на уровне приложения, которое приводит к тому, что каждое сообщение отправляется по новому соединению (и это не обязательно необычно, возможно или не удастся принять решение об этом поведение, в зависимости от того, какой пакет программного обеспечения вы используете);

  2. Ваш друг ошибается.

ответил Lightness Races in Orbit 14 MaramWed, 14 Mar 2018 01:01:31 +03002018-03-14T01:01:31+03:0001 2018, 01:01:31
4

Как указывали другие, TCP абсолютно разрешает соединение оставаться открытым на любое время, обмениваясь любым количеством «сообщений» в любом направлении за это время. Тем не менее, в конечном итоге это зависит от приложений (как клиента, так и сервера), чтобы определить, используется ли эта возможность.

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

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

Наконец, как отмечали другие, TCP ориентирован на потоки. Нет никакого кадрирования. Просто потому, что один одноранговый узел написал данные определенным образом (например, 1 1024-байтовый вызов записи, следующий за двумя 256-байтными вызовами записи), что не гарантирует, что другой одноранговый узел будет читать его в одинаковых кусках размера (например, он может получить все 1536 байт в одном прочитанном вызове). Таким образом, если вы отправляете несколько «сообщений» поверх необработанных сокетов TCP, вы должны предоставить свой собственный протокол кадрирования, чтобы очерчивать разные сообщения. Хотя, безусловно, есть простые способы сделать это, обычно это плохо, поскольку для решения этой проблемы существует множество протоколов, построенных поверх TCP. Для дальнейшего обсуждения проконсультируйтесь с этим: https://blog.stephencleary.com/2009 /04/message-framing.html

ответил Scot 14 MaramWed, 14 Mar 2018 03:17:35 +03002018-03-14T03:17:35+03:0003 2018, 03:17:35
0

Я думаю, что ваш друг говорил об HTTP, а не о TCP.

Первоначально HTTP был устаревшим протоколом: каждый HTTP-запрос использовал бы отдельное TCP-соединение. Вот почему для реализации сеансов нам нужны файлы cookie (или что-то подобное).

ответил reinierpost 14 MarpmWed, 14 Mar 2018 18:00:04 +03002018-03-14T18:00:04+03:0006 2018, 18:00:04
0

Вы упомянули о «единственном подключении и требовании нового порта каждый раз», и я бы понял, поскольку у вас много клиентов, использующих технику PAT в одной и той же сетевой среде для подключения к серверу вне вашей организации. У PAT будет предел 65535 (ограничение сеанса TCP на IPv4-адресе). Если это правда, у вас есть предел.

Открывает ли TCP новое соединение для каждого отправленного пакета? НЕТ, это не так, пока сеанс TCP действителен. и ...

ответил Hello 15 MaramThu, 15 Mar 2018 08:33:57 +03002018-03-15T08:33:57+03:0008 2018, 08:33:57
0

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

  

Использование ресурсов

     

Большинство реализаций выделяют запись в таблице, которая отображает сеанс в текущем процессе операционной системы. Поскольку TCP-пакеты не содержат идентификатор сеанса, обе конечные точки идентифицируют сеанс, используя адрес и порт клиента. Всякий раз, когда пакет принимается, реализация TCP должна выполнить поиск в этой таблице, чтобы найти процесс назначения. Каждая запись в таблице называется блоком управления передачей или TCB. Он содержит информацию о конечных точках (IP и порт), состоянии соединения, запуске данных об обменных пакетах и ​​буферах для отправки и получения данных.

     

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

Вкратце, TCP использует one очень конечный ressource, который представляет собой количество портов на клиенте (которое ограничено размером поля порта в заголовке TCP, 16 бит).

Таким образом, TCP есть , способный выходить из портов, если клиент открывает много TCP-соединений параллельно, не закрывая их. Проблема only происходит на стороне клиента, и не имеет значения, связаны ли соединения с одинаковыми или разными IP-адресами или серверами сервера.

В вашей настройке у вас, похоже, есть одно приложение, которое принимает во многих клиентских запросах ( эти могут быть отдельными TCP-запросами, так как, возможно, ваши клиенты используют это для регистрации некоторых событий в вашем приложении, t держите TCP-канал открытым между ними) и создайте новый внутренний запрос вашему брокеру Kafka (который очень легко может быть индивидуальным TCP-соединением, если вы решили реализовать их как это). В этом случае узкое место (с точки зрения ресурсов, а не производительности) будет заключаться в том, что вам удастся одновременно получать огромное количество запросов от ваших клиентов (для вас не проблема, так как на стороне сервера вам нужен только один порт для все они), и вы открываете огромное количество обратных запросов к вашему Kafka, и Kafka не может обрабатывать их достаточно быстро, в результате вы одновременно открываете соединения с более чем 16 битами.

Вы здесь собственный судья; проверьте свое приложение и попытайтесь выяснить, подключаетесь ли вы к Kafka с отдельным запросом каждый раз (возможно, через некоторый прокси REST API). Если вы это сделаете, и у вас будет огромное количество клиентов, то вы, безусловно, в опасности.

Если у вас есть только несколько клиентов, менее 65 тыс. символов и /или вы сохраняете одно соединение с вашим браузером Kafka, тогда все будет в порядке.

ответил AnoE 15 MaramThu, 15 Mar 2018 09:58:09 +03002018-03-15T09:58:09+03:0009 2018, 09:58:09

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132