Cua de connexions és el mecanisme mitjançant el qual un sistema operatiu manté temporalment connexions entrants pendents d'acceptació per part d'una aplicació servidora. En la programació de xarxes, aquest concepte s'associa sovint al terme anglès backlog, especialment en el context de la crida de sistema o mètode de sòcol listen(). La seva funció és permetre que un servidor pugui rebre diverses sol·licituds de connexió encara que l'aplicació no les accepti de manera immediata.
Aquest mecanisme és rellevant en servidors TCP, aplicacions web, serveis de xarxa i sistemes basats en programació asíncrona. Quan diversos clients intenten connectar-se a un servidor en un interval de temps molt curt, el sistema operatiu pot mantenir connexions pendents en una cua fins que l'aplicació les processi amb una operació d'acceptació. Si la cua s'omple, les noves connexions poden ser rebutjades o quedar sense resposta fins que el client esgota el temps d'espera, segons el sistema operatiu i la configuració de la pila de xarxa.
En aplicacions asíncrones, la cua de connexions actua com a amortidor entre l'arribada de connexions de xarxa i la capacitat del bucle d'esdeveniments per acceptar-les i delegar-ne el tractament a tasques o corrutines. Tot i això, la cua de connexions no substitueix els mecanismes de concurrència de l'aplicació, sinó que forma part de la infraestructura de xarxa sobre la qual aquests mecanismes treballen.
Funcionament general En un servidor de xarxa basat en sòcols, el procés habitual consisteix a crear un sòcol, associar-lo a una adreça i a un port, posar-lo en mode d'escolta i acceptar connexions entrants. En aquest model, el mètode o crida listen() indica al sistema operatiu que aquell sòcol ha de començar a escoltar connexions. El paràmetre anomenat habitualment backlog especifica la mida màxima de la cua de connexions pendents que poden esperar abans de ser acceptades per l'aplicació.
Aquesta cua no és una cua d'aplicació en el sentit habitual, sinó una estructura gestionada pel sistema operatiu dins de la pila de xarxa. L'aplicació servidora no hi insereix elements directament; simplement accepta connexions ja preparades mitjançant una crida com accept(). Quan una connexió és acceptada, el sistema retorna a l'aplicació un nou sòcol associat a aquell client concret, mentre que el sòcol original continua escoltant noves connexions.
La cua de connexions permet separar dos ritmes diferents: el ritme amb què arriben noves connexions des de la xarxa i el ritme amb què l'aplicació és capaç d'acceptar-les. Sense aquest mecanisme, un servidor podria perdre connexions en situacions normals de concurrència, per exemple quan diversos clients intenten connectar-se alhora.
Relació amb listen() i accept() La crida listen() transforma un sòcol vinculat a una adreça local en un sòcol passiu, preparat per rebre connexions. El paràmetre backlog no indica el nombre total de clients que un servidor pot atendre, sinó el nombre de connexions que poden quedar pendents d'acceptació en un moment determinat. Aquest valor no s'ha de confondre amb el nombre màxim de clients connectats simultàniament. Un servidor pot arribar a gestionar molts més clients al llarg del temps si accepta les connexions prou de pressa i delega el tractament de cada client a altres fils, processos, tasques o corrutines.
La crida accept() extreu una connexió de la cua de pendents i la lliura a l'aplicació. En servidors seqüencials, l'aplicació pot quedar ocupada tractant un client i trigar a acceptar-ne un altre. En servidors concurrents o asíncrons, en canvi, és habitual que el servidor accepti connexions de manera ràpida i després delegui la comunicació amb cada client a una unitat d'execució independent.
En Python, la biblioteca socket exposa aquest comportament mitjançant el mètode listen(). En entorns asíncrons, asyncio.start_server() també permet indicar un paràmetre backlog quan es crea un servidor TCP basat en fluxos.
Cua SYN i cua d'acceptació En TCP, l'establiment d'una connexió es basa en un intercanvi de missatges conegut com a encaixada de mans de tres passos. Per aquest motiu, en molts sistemes no hi ha una única cua conceptual, sinó diverses estructures internes relacionades amb l'estat de la connexió.
En sistemes Linux moderns, el paràmetre backlog de listen() fa referència principalment a la cua de sòcols completament establerts que encara esperen ser acceptats per l'aplicació. Aquesta cua es pot entendre com la cua d'acceptació, perquè conté connexions que ja han completat l'establiment TCP però que encara no han estat retornades a l'aplicació mitjançant accept().
Les connexions que encara no han completat l'encaixada de mans TCP poden estar gestionades per una altra cua, sovint anomenada cua SYN, o per altres mecanismes interns del nucli. En Linux, la mida màxima de la cua de connexions incompletes es pot controlar mitjançant paràmetres del sistema com tcp_max_syn_backlog, mentre que la cua de connexions ja establertes està limitada pel valor de backlog i per límits globals del sistema, com somaxconn.
Aquesta distinció és important perquè el comportament exacte del paràmetre pot variar segons el sistema operatiu. Per això, el valor indicat per l'aplicació s'ha d'entendre com una petició al sistema operatiu, no sempre com una garantia exacta. Algunes implementacions poden limitar-lo, arrodonir-lo o substituir-lo per un valor màxim permès.
Saturació de la cua La saturació de la cua de connexions es produeix quan arriben més connexions de les que el sistema pot mantenir pendents d'acceptació. Aquesta situació pot aparèixer durant pics sobtats de trànsit, proves de càrrega, atacs de denegació de servei o aplicacions servidores que accepten connexions massa lentament.
Quan la cua és plena, el sistema pot rebutjar noves connexions o deixar que els clients esperin fins que es produeixi un temps d'espera. Des del punt de vista de l'usuari, això es pot manifestar com una connexió lenta, un error de connexió o una aplicació que sembla no respondre. Des del punt de vista del servidor, una cua plena pot indicar que el valor de backlog és massa baix, que el servidor no accepta connexions prou ràpidament o que la càrrega entrant supera la capacitat real del sistema.
L'augment del backlog pot ajudar a absorbir ràfegues curtes de connexions, però no resol per si sol un problema de capacitat. Si l'aplicació no pot processar els clients amb prou rapidesa, una cua més gran només pot retardar el problema i incrementar la latència. Per això, aquest paràmetre s'ha d'ajustar conjuntament amb altres factors, com el nombre de treballadors, la velocitat d'acceptació, els límits del sistema operatiu i els recursos disponibles.
Paper en servidors asíncrons En la programació asíncrona, la cua de connexions continua sent un mecanisme del sistema operatiu, però la manera com l'aplicació accepta i gestiona connexions és diferent. En lloc de crear necessàriament un fil per cada client, un servidor asíncron pot utilitzar un bucle d'esdeveniments per detectar quan hi ha connexions disponibles i crear tasques per gestionar-les de manera cooperativa.
En el cas d'asyncio, la funció asyncio.start_server() crea un servidor TCP i associa a cada nova connexió una funció de gestió de client. Aquesta funció rep habitualment un objecte StreamReader i un objecte StreamWriter, que permeten llegir i escriure dades de manera asíncrona. Si la funció de gestió és una corrutina, el mateix mecanisme d'asyncio la programa automàticament com una tasca.
Això significa que la cua de connexions forma part de la frontera entre el sistema operatiu i l'aplicació asíncrona. Primer, el sistema operatiu rep les connexions entrants i les manté pendents quan cal. Després, el servidor asíncron les accepta i el bucle d'esdeveniments n'organitza el tractament mitjançant tasques cooperatives. Aquesta separació permet que un sol fil d'execució pugui gestionar moltes connexions obertes, sempre que les operacions d'entrada/sortida no bloquegin el bucle d'esdeveniments.
Per tant, el backlog no és una cua de tasques d'asyncio, sinó una cua del sistema operatiu que existeix abans que la connexió sigui lliurada al codi asíncron de l'aplicació. Tanmateix, el fet que l'aplicació sigui asíncrona no elimina la necessitat de configurar correctament la cua de connexions. Si el ritme d'arribada de clients és superior a la velocitat amb què el servidor pot acceptar-los, la cua pot omplir-se igualment.
Per això, en servidors asíncrons d'alt trànsit, el backlog s'ha de considerar conjuntament amb altres mecanismes de control, com els temps d'espera, la limitació de connexions, la contrapressió i la gestió dels buffers d'escriptura.
Configuració i consideracions pràctiques La mida òptima de la cua de connexions depèn del tipus de servei, del patró de trànsit i del sistema operatiu. Un valor massa baix pot provocar errors durant pics normals de connexions. Un valor massa alt pot ocultar problemes de rendiment i augmentar el temps que els clients passen esperant abans de ser acceptats.
En sistemes de producció, la configuració del backlog sol combinar-se amb límits del sistema operatiu i del servidor d'aplicacions. Per exemple, en Linux, el valor efectiu pot estar limitat per paràmetres del nucli, mentre que en Windows la documentació de Winsock defineix el backlog com la longitud màxima de la cua de connexions pendents i permet utilitzar valors especials com SOMAXCONN perquè el proveïdor de serveis esculli un valor raonable.
La configuració també depèn del model d'execució. Un servidor que accepta connexions i les delega ràpidament pot mantenir la cua buida en condicions normals. En canvi, un servidor que fa càlculs costosos abans d'acceptar el següent client pot omplir-la fàcilment. Per aquest motiu, en aplicacions concurrents és habitual separar l'acceptació de connexions del processament posterior de les peticions.
Vegeu també Transmission Control Protocol Servidor web Programació asíncrona Bucle d'esdeveniments Entrada/sortida Congestió de xarxa
Referències
Categoria:Protocols de xarxa Categoria:Programació Categoria:Internet