Cosa limita il numero massimo di connessioni su un server Linux?


90

Quali parametri del kernel o altre impostazioni controllano il numero massimo di socket TCP che possono essere aperti su un server Linux? Quali sono gli svantaggi di consentire più connessioni?

Durante il test di caricamento di un server Apache con ab ho notato che è abbastanza semplice massimizzare le connessioni aperte sul server. Se si interrompe l'opzione -k di ab, che consente il riutilizzo della connessione e si fa in modo che invii più di circa 10.000 richieste, Apache serve le prime circa 11.000 richieste e si interrompe per 60 secondi. Uno sguardo all'output di netstat mostra 11.000 connessioni nello stato TIME_WAIT. Apparentemente, questo è normale. Le connessioni vengono mantenute aperte per un valore predefinito di 60 secondi anche dopo che il client ha terminato di utilizzarle per motivi di affidabilità TCP .

Sembra che questo sarebbe un modo semplice per fare un server e mi chiedo quali siano le solite regolazioni e precauzioni per questo.

Ecco il mio risultato del test:

# ab -c 5 -n 50000 http://localhost/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
apr_poll: The timeout specified has expired (70007)
Total of 11655 requests completed

Ecco il comando netstat che eseguo durante il test:

 # netstat --inet -p | grep "localhost:www" | sed -e 's/ \+/ /g' | cut -d' ' -f 1-4,6-7 | sort | uniq -c 
  11651 tcp 0 0 localhost:www TIME_WAIT -
      1 tcp 0 1 localhost:44423 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44424 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44425 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44426 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44428 SYN_SENT 7831/ab

Risposte:


64

Ho finalmente trovato l'impostazione che è stata davvero limitare il numero di connessioni: net.ipv4.netfilter.ip_conntrack_max. È stato impostato su 11.776 e qualunque cosa io abbia impostato è il numero di richieste che posso servire nel mio test prima di dover aspettare tcp_fin_timeoutsecondi per rendere disponibili più connessioni. La conntracktabella è ciò che il kernel utilizza per tenere traccia dello stato delle connessioni, quindi una volta pieno, il kernel inizia a eliminare i pacchetti e a stamparlo nel registro:

Jun  2 20:39:14 XXXX-XXX kernel: ip_conntrack: table full, dropping packet.

Il passo successivo è stato far sì che il kernel riciclasse tutte quelle connessioni nello TIME_WAITstato piuttosto che far cadere i pacchetti. Potrei farlo accadere accendendo tcp_tw_recycleo aumentando ip_conntrack_maxper essere maggiore del numero di porte locali rese disponibili per le connessioni da ip_local_port_range. Immagino che quando il kernel esce dalle porte locali inizia a riciclare le connessioni. Questo utilizza più connessioni di tracciamento della memoria ma sembra la soluzione migliore rispetto all'accensione tcp_tw_recyclepoiché i documenti implicano che ciò è pericoloso.

Con questa configurazione posso eseguire ab tutto il giorno e non finire mai le connessioni:

net.ipv4.netfilter.ip_conntrack_max = 32768
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_max_orphans = 8192
net.ipv4.ip_local_port_range = 32768    61000

L' tcp_max_orphansimpostazione non ha avuto alcun effetto sui miei test e non so perché. Penserei che chiuderebbe i collegamenti nello TIME_WAITstato una volta che ce ne fossero 8192, ma non lo fa per me.


3
Dove configuriamo questi parametri?
Codevalley,

2
@Codevalley Potrebbe dipendere dal sistema ma su Ubuntu Server vanno in /etc/sysctl.conf
Ben Williams,

24

Volete davvero vedere che cosa offre il filesystem / proc a questo proposito.

In quest'ultima pagina, potresti trovare le seguenti cose di tuo interesse:

  • / proc / sys / net / ipv4 / tcp_max_orphans , che controlla il numero massimo di socket detenuti dal sistema non collegati a qualcosa. Aumentare questo può consumare fino a 64 kbyte di memoria non scambiabile per socket orfano .
  • / proc / sys / net / ipv4 / tcp_orphan_retries , che controlla la quantità di tentativi prima che un socket sia orfano e chiuso. C'è una nota specifica in quella pagina sui server web di tuo interesse diretto ...

tcp_max_orphans è interessante ma sembra che non funzioni. Quando provo a misurare socket orfani durante il mio test, ne vedo 11.651 mentre tcp_max_orphans è 8.092. # netstat --inet -p | grep "localhost: www" | sed -e 's / \ + / / g' | cut -d '' -f 1-4,6-7 | ordina | uniq -c 11651 tcp 0 0 localhost: www TIME_WAIT -
Ben Williams,

Guarda l'impostazione tcp_orphan_retries - l'idea è che le prese vengano "abbattute" più velocemente ...
Avery Payne,

Il suggerimento di @Jauder Ho + tcp_orphan_retries sembra una potenziale vittoria per la tua situazione.
Avery Payne,

3

Non penso che ci sia un parametro sintonizzabile per impostarlo direttamente. Questo rientra nella categoria di ottimizzazione TCP / IP. Per scoprire cosa puoi sintonizzare, prova 'man 7 tcp'. Il sysctl ('man 8 sysctl') è usato per impostarli. 'sysctl -a | grep tcp 'ti mostrerà la maggior parte di ciò che puoi sintonizzare, ma non sono sicuro che mostrerà tutti loro. Inoltre, a meno che ciò non sia cambiato, i socket TCP / IP aperti sembrano descrittori di file. Quindi questa e la prossima sezione di quel link potrebbero essere ciò che stai cercando.


2

Prova a impostare anche l'impostazione tcp_fin_timeout. Questo dovrebbe chiudere TIME_WAIT più rapidamente.

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

Attento qui! Sperimentato nel modo più duro. "Ciò può causare la caduta di frame con bilanciamento del carico e NAT, utilizzarlo solo per un server che comunica solo sulla rete locale." - wiki.archlinux.org/index.php/Sysctl
Henk

@Henk Immagino tcp_tw_recycleche sia potenzialmente pericoloso. tcp_tw_reuseè più sicuro e non vedo alcun motivo per usarli contemporaneamente.
Vladislav Rastrusny il

2

Lo stock apache (1) veniva predefinito per supportare solo 250 connessioni simultanee - se volevi di più, c'era un file di intestazione da modificare per consentire più sessioni simultanee. Non so se questo è ancora vero con Apache 2.

Inoltre, è necessario aggiungere un'opzione per consentire un sacco di descrittori di file più aperti per l'account che esegue Apache, cosa che i commenti precedenti non sottolineano.

Presta attenzione alle impostazioni del tuo lavoratore e al tipo di timeout keepalive che hai all'interno di Apache stesso, quanti server di riserva hai in esecuzione contemporaneamente e quanto velocemente questi processi extra vengono uccisi.


1

È possibile ridurre il tempo trascorso nello stato TIME_WAIT (impostare net.ipv4.tcp_fin_timeout). È possibile sostituire Apache con YAWS o nginx o qualcosa di simile.

Gli svantaggi di più connessioni generalmente comportano l'utilizzo della memoria e, se si dispone di un processo di fork, molti processi figlio che sommergono la CPU.


1
tcp_fin_timeout non è per impostare la scadenza di TIME-WAIT, che non è modificabile al di fuori della ricostruzione del kernel, ma per FIN, come indica il nome.
Alexandr Kurilin,

0

Il numero assoluto di socket che possono essere aperti su un singolo indirizzo IP è 2 ^ 16 ed è definito da TCP / UDP, non dal kernel.


6
No non lo è. Puoi aprirne di più, poiché la porta locale non deve essere univoca purché gli indirizzi remoti siano diversi. Inoltre, l'OP ha detto per server e puoi avere> 1 indirizzo per server.
Mark R

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.