Cela peut être une question idiote, mais quelques copains et moi avons discuté des limites potentielles de TCP. Nous avons une application qui va écouter les clients (pensez à une passerelle) et acheminer toutes les données des clients connectés via un seul éditeur kafka connecté vers un sujet.
Un de mes amis dit que TCP sera un problème pour cette passerelle car il va établir une nouvelle connexion pour chaque message qu'il envoie (pas kafka mais le protocole de transport sous-jacent lui-même est le problème), nécessitant un nouveau port à chaque fois. Au rythme auquel nous enverrons ces messages clients (gigaoctets), kafka manquera de ports pour lire depuis ??
J'ai fait du développement depuis plusieurs années et je n'en ai jamais entendu parler auparavant et j'aimerais avoir une compréhension de niveau inférieur (que je pensais avoir) du fonctionnement de TCP. Ma compréhension est que lorsque vous établissez une connexion TCP, cette connexion reste ouverte jusqu'à ce qu'elle soit expirée par l'application ou fermée de force par le serveur ou le client. Les données envoyées via cette connexion sont un flux et n'ouvriront / fermeront pas de nouvelles connexions quels que soient les 3 V (volume, vitesse, variété).
En ce qui concerne les ports, un port est utilisé pour la diffusion et le port de descripteur de fichier interne est quelque chose que l'application gère pour la lecture / écriture de clients individuels. Je n'ai jamais compris TCP pour établir de nouvelles connexions pour chaque paquet qu'il écrit.
Je m'excuse à l'avance si cette question n'est pas directe et ou trop vague. Je suis vraiment déconcerté et j'espère que quelqu'un pourrait fournir un peu plus de contexte à ce que disent mes collègues?
la source
SO_REUSEADDR
pour fermer les sockets plus rapidement, augmenter la plage de ports éphémères, etc. De plusTCP_FASTOPEN
, plusieurs bascules au niveau du système d'exploitation peuvent être utilisées pour contourner d'autres limitations bien connues de TCP. Quoi qu'il en soit, il est inutile de discuter des limites de TCP lorsque vous n'avez même pas de charge de travail à tester.Réponses:
Votre ami est très confus. TCP est un protocole orienté flux. Il n'a aucune notion de messages. Bien sûr, il utilise des paquets au niveau de la couche IP, mais pour l'application, c'est un détail d'implémentation. TCP insère les limites des paquets là où il est logique de le faire, et pas nécessairement une fois par
write()
ousend()
. De même, il combine les paquets successifs si vous en recevez plusieurs entre les appels versread()
ourecv()
.Il va sans dire que cette conception orientée flux serait totalement irréalisable si chaque envoi établissait une nouvelle connexion. Ainsi, la seule façon d'établir une nouvelle connexion est de fermer et de rouvrir la connexion manuellement.
(En pratique, la plupart des protocoles construits au-dessus de TCP ont quelque chose qui ressemble à des messages, tels que des requêtes et des réponses HTTP. Mais TCP ne connaît pas ou ne se soucie pas de la structure de ces choses.)
Il est possible que votre ami ait pensé à UDP, qui a des messages, mais est également sans connexion. La plupart des implémentations de socket vous permettent de «connecter» un socket UDP à un hôte distant, mais c'est juste un moyen pratique pour éviter d'avoir à spécifier à plusieurs reprises l'adresse IP et le port. Il ne fait rien au niveau du réseau. Néanmoins, vous pouvez suivre manuellement les pairs avec lesquels vous parlez sous UDP. Mais si vous le faites, décider de ce qui compte comme une "connexion" est votre problème, pas celui du système d'exploitation. Si vous souhaitez rétablir une "connexion" sur chaque message, vous pouvez le faire. Ce n'est probablement pas une très bonne idée, cependant.
la source
Du point de vue de TCP, il n'y a ni client ni serveur (client / serveur est un concept d'application hors sujet ici). TCP établit une connexion entre homologues, et les deux homologues peuvent envoyer et recevoir sur la connexion jusqu'à ce que l'un des homologues la ferme ou expire de l'inactivité.
Ce qui peut prêter à confusion, c'est que certaines applications, par exemple les navigateurs, ouvriront plusieurs connexions afin de charger simultanément des éléments comme des éléments d'une page Web.
TCP n'ouvre pas une nouvelle connexion pour chaque segment qu'il envoie, mais une application peut ouvrir plusieurs connexions TCP. En outre, lorsqu'une connexion TCP est fermée, le port TCP utilisé dans la connexion est libéré et il est disponible pour être utilisé à nouveau. Cette réponse donne quelques informations et vous indique la RFC pour TCP.
la source
Non, TCP n'a pas besoin d'ouvrir une nouvelle connexion pour chaque paquet envoyé.
Vous pouvez envoyer plusieurs paquets par le biais de connexions persistantes HTTP , où:
Vous trouverez ci-joint une figure montrant la différence entre plusieurs connexions (plusieurs connexions établies pour envoyer un objet par connexion) et une connexion persistante (une connexion établie et plusieurs objets qui y sont envoyés):
Source: https://www.vcloudnine.de/how-to-dramately-improve-website-load-times/
la source
Votre interprétation du fonctionnement de TCP est correcte.
Quant à ce que votre ami a dit, je vois deux possibilités ici:
Vous avez mal compris votre ami, qui faisait référence à une limitation de la couche d'application qui se traduit par l'envoi de chaque message via une nouvelle connexion (et ce n'est pas nécessairement inhabituel; il peut ou non être possible de décider de ce comportement, selon le logiciel pile que vous utilisez);
Votre ami a tort.
la source
Comme d'autres l'ont souligné, TCP permet absolument à une connexion de rester ouverte pendant un certain temps, en échangeant n'importe quel nombre de «messages» dans les deux sens pendant ce temps. Cela dit, il appartient en dernier ressort aux applications (client et serveur) de déterminer si cette capacité est utilisée.
Afin de réutiliser la connexion TCP existante (socket), l'application cliente doit garder cette socket ouverte et l'utiliser lorsqu'elle a besoin d'écrire plus de données. Si le client ne le fait pas, mais jette à la place l'ancien socket et ouvre un nouveau socket à chaque fois qu'il en a besoin, alors il forcera une nouvelle connexion qui pourrait causer des problèmes de ressources sur le client ou le serveur si cela est fait assez fréquemment pour épuiser soit le pool de connexion de la pile TCP.
De même, le serveur doit être suffisamment intelligent pour garder le socket ouvert sur le côté et attendre plus de données. Comme le client, il a la possibilité de fermer le socket, auquel cas un client tolérant aux pannes souhaitant envoyer plus de données n'aura d'autre choix que d'ouvrir un nouveau socket, ce qui entraînera le même problème.
Enfin, comme d'autres l'ont mentionné, TCP est orienté flux. Il n'y a aucun encadrement. Tout simplement parce qu'un homologue a écrit les données d'une manière particulière (par exemple, 1 appel d'écriture de 1 024 octets suivi de 2 256 appels d'écriture d'octets), cela ne garantit pas que l'autre homologue les lira dans les mêmes morceaux (par exemple, il pourrait obtenir tous les 1 536 octets). en un seul appel de lecture). Ainsi, si vous envoyez plusieurs "messages" sur des sockets TCP bruts, vous devez fournir votre propre protocole de trame pour délimiter les différents messages. Bien qu'il existe certainement des moyens simples de le faire, il est généralement peu judicieux car il existe de nombreux protocoles construits sur TCP pour résoudre ce problème. Pour plus de discussion, consultez ceci: https://blog.stephencleary.com/2009/04/message-framing.html
la source
Je pense que votre ami parlait de HTTP, pas de TCP.
HTTP était à l'origine un protocole sans état: chaque requête HTTP utiliserait une connexion TCP distincte. C'est pourquoi nous avons besoin de cookies (ou quelque chose de similaire) pour implémenter les sessions.
la source
Vous avez mentionné "une connexion unique et nécessitant un nouveau port à chaque fois", et j'interpréterais que vous avez de nombreux clients utilisant la technique PAT dans le même environnement réseau pour se connecter au serveur en dehors de votre organisation. Le PAT aurait la limite de 65535 (limite de session TCP sur l'adresse IPv4). Si c'est vrai, vous avez la limite.
TCP ouvre-t-il une nouvelle connexion pour chaque paquet envoyé? NON, cela ne dure pas tant que la session TCP est valide. et ...
la source
J'aime l' excellente page wikipedia sur TCP . Il montre clairement ce qui se passe avec le numéro de port. Par chance, il contient également un chapitre utile sur l'utilisation des ressources:
En bref, TCP utilise une ressource très finie, qui est le nombre de ports sur le client (qui est limité par la taille du champ de port dans l'en-tête TCP, 16 bits).
Ainsi, TCP est capable de manquer de ports, si un client ouvre un grand nombre de connexions TCP en parallèle sans les fermer. Le problème se produit uniquement côté client, et il n'importe pas si les connexions sont avec les mêmes adresses IP de serveur ou ports de serveur.
Dans votre environnement, vous semblez avoir une application qui accepte de nombreuses demandes des clients ( cesIl peut s'agir de demandes TCP individuelles, car vos clients l'utilisent peut-être pour consigner certains événements dans votre application et ne maintiennent pas le canal TCP ouvert entre eux), et créer une nouvelle demande interne à votre courtier Kafka (qui pourrait très facilement être des connexions TCP individuelles si vous avez choisi de les implémenter comme ça). Dans ce cas, le goulot d'étranglement (en termes de ressources, pas de performances) serait si vous parvenez à obtenir un grand nombre de demandes en même temps de vos clients (pas de problème pour vous, car côté serveur vous n'avez besoin que d'un port pour tous), et vous ouvrez un grand nombre de demandes de transfert vers votre Kafka, et Kafka n'est pas en mesure de les traiter assez rapidement, vous vous retrouvant avec plus de 16 bits de connexions ouvertes simultanément.
Vous êtes le propre juge ici; vérifiez votre application et essayez de savoir si vous vous connectez à Kafka avec une demande distincte à chaque fois (peut-être via un proxy API REST). Si vous le faites et que vous avez un grand nombre de clients, vous êtes certainement en danger.
Si vous n'avez qu'une poignée de clients, moins de 65k-ish, et / ou vous gardez une seule connexion à votre navigateur Kafka, alors tout ira bien.
la source