Um socket é um ponto final lógico de comunicação bidirecional entre dois programas em uma rede, representado pela combinação de um endereço IP e uma porta. Para manter milhares de conexões simultâneas, o backend moderno abandonou o modelo tradicional de 'uma thread por conexão' (que consumia muita memória RAM) e passou a utilizar I/O assíncrono e multiplexação de eventos. Tecnologias como epoll no Linux e kqueue no BSD permitem que uma única thread gerencie milhares de sockets abertos ao mesmo tempo, monitorando ativamente quais conexões estão prontas para enviar ou receber dados, reduzindo drasticamente o custo computacional do servidor.
Principais Aprendizados
- Sockets são abstrações lógicas (file descriptors) que o sistema operacional utiliza para enviar e receber pacotes de dados pela rede.
- O modelo antigo de servidores falhava em alta escala devido ao Problema C10K, esgotando a memória ao criar uma thread para cada usuário conectado.
- Servidores modernos, como Nginx e Node.js, usam Event Loops e I/O não-bloqueante para sustentar milhões de conexões simultâneas com eficiência.
O que é um Socket na Prática?
Toda vez que você acessa um site, joga online ou envia uma mensagem no WhatsApp, seu dispositivo precisa de uma via de comunicação direta com um servidor. Essa via é o socket. Em termos técnicos, originados na API de Berkeley Sockets em 1983, um socket é a combinação de um Endereço IP (que identifica a máquina) e uma Porta (que identifica o processo ou aplicação).
Para o sistema operacional Linux, tudo é um arquivo. Portanto, quando uma conexão de rede é estabelecida, o sistema cria um 'File Descriptor' (descritor de arquivo). O backend simplesmente lê e escreve dados nesse descritor como se estivesse manipulando um arquivo de texto comum. Dominar esse conceito é um dos pilares de redes que todo programador precisa entender para construir aplicações robustas.

O Problema C10K: Por que os servidores antigos travavam?
Nos primórdios da web, servidores como o Apache (em suas primeiras versões) usavam um modelo chamado Thread-per-Connection ou Process-per-Connection. Isso significava que, para cada novo socket aberto, o sistema operacional precisava criar uma nova thread ou processo.
Segundo o engenheiro de software Dan Kegel, que documentou esse gargalo em 1999, isso gerava o famoso Problema C10K (como lidar com 10 mil conexões simultâneas). Cada thread consumia cerca de 1MB a 2MB de memória RAM. Se um servidor recebesse 10.000 conexões, ele precisaria de dezenas de gigabytes de RAM apenas para manter as conexões ociosas, sem contar o processamento real. Além disso, a CPU perdia muito tempo fazendo a troca de contexto (Context Switching) entre milhares de threads, levando o servidor ao colapso.

Como o Backend Moderno Lida com Milhares de Conexões
Para resolver o problema do consumo de memória e CPU, a arquitetura dos servidores mudou drasticamente. A solução foi parar de criar threads e focar na eficiência.
I/O Assíncrono e Multiplexação
Em vez de uma thread ficar bloqueada esperando um usuário enviar dados, o backend moderno usa I/O não-bloqueante (Non-blocking I/O). O servidor delega a vigilância dos sockets para o kernel do sistema operacional usando a chamada de sistema epoll do Linux (ou kqueue no macOS/FreeBSD).
A multiplexação permite que uma única thread pergunte ao sistema operacional: 'Dentre esses 10.000 sockets, quais têm dados prontos para leitura agora?'. O SO responde instantaneamente apenas com os sockets ativos, economizando recursos massivos.
A Ascensão do Event Loop
Essa arquitetura baseada em eventos deu origem ao famoso Event Loop. É graças a ele que tecnologias como Node.js conseguem ser extremamente rápidas, mesmo sendo single-thread. Esse também é o fator decisivo na hora de decidir qual servidor web escolher, já que o Nginx foi construído puramente em cima dessa arquitetura orientada a eventos, desbancando servidores mais antigos em testes de estresse.

Sockets vs WebSockets: Qual a diferença?
É comum confundir os termos. Um 'socket' padrão (TCP/UDP) opera na camada de transporte (Camada 4 do modelo OSI). Ele é a fundação bruta da rede. Já o WebSocket é um protocolo que opera na camada de aplicação (Camada 7), construído em cima do HTTP e do TCP. Se você deseja criar comunicação em tempo real para um chat no navegador, você usará WebSockets, que por baixo dos panos, utilizam sockets TCP gerenciados pelo seu backend.
Escalando para Milhões de Conexões
Mesmo com o Event Loop, um único servidor físico tem limites de CPU e banda de rede (o chamado problema C10M, ou 10 milhões de conexões). Quando um servidor não aguenta mais, entra a necessidade de entender a diferença entre escalabilidade horizontal vs vertical. Ao escalar horizontalmente, colocamos um Load Balancer (Balanceador de Carga) na frente da infraestrutura. Ele recebe as conexões dos clientes e distribui os sockets entre dezenas de servidores de backend menores, garantindo que o sistema nunca caia.
Perguntas Frequentes
1. Qual o limite máximo de portas e sockets em um servidor?
O limite teórico de portas TCP em um único endereço IP é de 65.535 portas, já que a porta é representada por um número de 16 bits. No entanto, o número de conexões simultâneas (sockets) pode ser muito maior, pois um socket é definido pelo quarteto: IP de Origem, Porta de Origem, IP de Destino e Porta de Destino. Um servidor pode aceitar milhões de conexões se vierem de IPs diferentes.
2. Sockets consomem muita memória?
Um socket em si consome muito pouca memória (apenas alguns kilobytes para os buffers de envio e recebimento do kernel). O que consumia muita memória no passado era a criação de processos ou threads dedicadas para cada socket. Com I/O assíncrono, o custo de memória por conexão é mínimo.
3. Uma API REST usa sockets?
Sim! Toda comunicação na internet utiliza sockets. Para entender como APIs conversam, saiba que uma requisição REST usa o protocolo HTTP, que por sua vez abre um socket TCP para transferir os dados, fechando-o (ou mantendo-o vivo via Keep-Alive) após a resposta.
0 Comentários