Il numero massimo di connessioni è influenzato da determinati limiti sia lato client che lato server, anche se in modo leggermente diverso.
Sul lato client:
aumentare l'intervallo di porte ephermal e diminuire il valoretcp_fin_timeout
Per scoprire i valori predefiniti:
sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_fin_timeout
L'intervallo di porte ephermal definisce il numero massimo di socket in uscita che un host può creare da un determinato indirizzo IP. La fin_timeout
definisce il tempo minimo queste prese rimarranno in TIME_WAIT
stato (inutilizzabile dopo essere stato usato una volta). I valori predefiniti di sistema usuali sono:
net.ipv4.ip_local_port_range = 32768 61000
net.ipv4.tcp_fin_timeout = 60
Ciò significa sostanzialmente che il tuo sistema non può garantire costantemente più di (61000 - 32768) / 60 = 470
prese al secondo. Se non sei soddisfatto, potresti iniziare con l'aumento di port_range
. Impostare l'intervallo su 15000 61000
è abbastanza comune in questi giorni. È possibile aumentare ulteriormente la disponibilità diminuendo il fin_timeout
. Supponiamo che tu faccia entrambe le cose, dovresti vedere più di 1500 connessioni in uscita al secondo, più facilmente.
Per modificare i valori :
sysctl net.ipv4.ip_local_port_range="15000 61000"
sysctl net.ipv4.tcp_fin_timeout=30
Quanto sopra non deve essere interpretato come i fattori che influenzano la capacità del sistema di stabilire connessioni in uscita al secondo. Ma piuttosto questi fattori influenzano la capacità del sistema di gestire connessioni simultanee in modo sostenibile per lunghi periodi di "attività".
I valori predefiniti di Sysctl su una tipica scatola Linux per tcp_tw_recycle
& tcp_tw_reuse
sarebbero
net.ipv4.tcp_tw_recycle=0
net.ipv4.tcp_tw_reuse=0
Questi non consentono una connessione da una presa "usata" (in stato di attesa) e costringono le prese a durare l'intero time_wait
ciclo. Consiglio di impostare:
sysctl net.ipv4.tcp_tw_recycle=1
sysctl net.ipv4.tcp_tw_reuse=1
Ciò consente il ciclo rapido delle prese nello time_wait
stato e il loro riutilizzo. Prima di apportare questa modifica, tuttavia, assicurarsi che ciò non sia in conflitto con i protocolli da utilizzare per l'applicazione che necessita di questi socket. Assicurati di leggere il post " Far fronte al TCP TIME-WAIT" di Vincent Bernat per capire le implicazioni. L' net.ipv4.tcp_tw_recycle
opzione è piuttosto problematica per i server pubblici in quanto non gestirà le connessioni da due computer diversi dietro lo stesso dispositivo NAT , il che è un problema difficile da rilevare e in attesa di morderti. Si noti che net.ipv4.tcp_tw_recycle
è stato rimosso da Linux 4.12.
Sul lato server:
il net.core.somaxconn
valore ha un ruolo importante. Limita il numero massimo di richieste in coda a un socket di ascolto. Se sei sicuro della capacità della tua applicazione server, aumentalo da 128 a qualcosa come 128 a 1024. Ora puoi approfittare di questo aumento modificando la variabile di ascolto del backlog nella chiamata di ascolto della tua applicazione, a un numero intero uguale o superiore.
sysctl net.core.somaxconn=1024
txqueuelen
Anche il parametro delle tue schede Ethernet ha un ruolo da svolgere. I valori predefiniti sono 1000, quindi aumentali fino a 5000 o anche di più se il tuo sistema è in grado di gestirlo.
ifconfig eth0 txqueuelen 5000
echo "/sbin/ifconfig eth0 txqueuelen 5000" >> /etc/rc.local
Allo stesso modo aumentare i valori per net.core.netdev_max_backlog
e net.ipv4.tcp_max_syn_backlog
. I loro valori predefiniti sono rispettivamente 1000 e 1024.
sysctl net.core.netdev_max_backlog=2000
sysctl net.ipv4.tcp_max_syn_backlog=2048
Ora ricordati di avviare le applicazioni lato client e lato server aumentando gli ultrasuoni FD, nella shell.
Oltre alla precedente tecnica più popolare utilizzata dai programmatori è quella di ridurre il numero di chiamate in scrittura tcp . La mia preferenza è quella di utilizzare un buffer in cui invio i dati che desidero inviare al client e quindi, nei punti appropriati, scrivo i dati bufferizzati nel socket effettivo. Questa tecnica mi consente di utilizzare pacchetti di dati di grandi dimensioni, ridurre la frammentazione, ridurre l'utilizzo della CPU sia a livello di utente che a livello di kernel.