Perché il mio server Web sta abbandonando le connessioni con un reset TCP a carico elevato?


10

Ho una piccola configurazione VPS con nginx. Voglio sfruttare al massimo le prestazioni possibili, quindi ho sperimentato l'ottimizzazione e i test di carico.

Sto usando Blitz.io per fare i test di carico OTTENENDO un piccolo file di testo statico e incappando in uno strano problema in cui il server sembra inviare reimpostazioni TCP una volta che il numero di connessioni simultanee raggiunge circa il 2000. So che questo è molto una grande quantità, ma usando htop il server ha ancora molto da risparmiare in termini di tempo e memoria della CPU, quindi vorrei capire l'origine di questo problema per vedere se posso spingerlo ulteriormente.

Sto eseguendo Ubuntu 14.04 LTS (64 bit) su un VPS Linode da 2 GB.

Non ho abbastanza reputazione per pubblicare direttamente questo grafico, quindi ecco un link al grafico Blitz.io:

inserisci qui la descrizione dell'immagine

Ecco alcune cose che ho fatto per cercare di capire l'origine del problema:

  • Il valore di configurazione nginx worker_rlimit_nofileè impostato su 8192
  • hanno nofileimpostato a 64000 per entrambi i limiti hard e soft per roote www-datautente (quello che viene eseguito come nginx) a/etc/security/limits.conf
  • non ci sono indicazioni in cui qualcosa vada storto /var/log/nginx.d/error.log(in genere, se si verificano limiti ai descrittori di file, nginx stampa messaggi di errore che lo dicono)

  • Ho installato uww, ma nessuna regola di limitazione della velocità. Il registro ufw indica che nulla è stato bloccato e ho provato a disabilitare ufw con lo stesso risultato.

  • Non ci sono errori indicativi in /var/log/kern.log
  • Non ci sono errori indicativi in /var/log/syslog
  • Ho aggiunto i seguenti valori /etc/sysctl.confe li ho caricati sysctl -psenza alcun effetto:

    net.ipv4.tcp_max_syn_backlog = 1024
    net.core.somaxconn = 1024
    net.core.netdev_max_backlog = 2000
    

Qualche idea?

EDIT: ho fatto un nuovo test, passando a 3000 connessioni su un file molto piccolo (solo 3 byte). Ecco il grafico Blitz.io:

Grafico Blitz.io

Ancora una volta, secondo Blitz, tutti questi errori sono errori "Ripristino connessione TCP".

Ecco il grafico della larghezza di banda di Linode. Tieni presente che si tratta di una media di 5 minuti, quindi il suo passa basso è filtrato un po '(la larghezza di banda istantanea è probabilmente molto più alta), ma comunque non è niente:

inserisci qui la descrizione dell'immagine

PROCESSORE:

inserisci qui la descrizione dell'immagine

I / O:

inserisci qui la descrizione dell'immagine

Ecco htopverso la fine del test: htop

Ho anche acquisito parte del traffico utilizzando tcpdump su un test diverso (ma simile), iniziando l'acquisizione quando sono iniziati gli errori: sudo tcpdump -nSi eth0 -w /tmp/loadtest.pcap -s0 port 80

Ecco il file se qualcuno vuole dare un'occhiata (~ 20 MB): https://drive.google.com/file/d/0B1NXWZBKQN6ETmg2SEFOZUsxV28/view?usp=sharing

Ecco un grafico della larghezza di banda di Wireshark:

inserisci qui la descrizione dell'immagine (La riga contiene tutti i pacchetti, le barre blu sono errori TCP)

Dalla mia interpretazione della cattura (e non sono un esperto), sembra che i flag TCP RST provengano dall'origine di test del carico, non dal server. Quindi, supponendo che qualcosa non vada storto dal lato del servizio di test del carico, è sicuro supporre che questo sia il risultato di una sorta di gestione della rete o di mitigazione DDOS tra il servizio di test del carico e il mio server?

Grazie!


Il tuo provider sta facendo una sorta di mitigazione DDoS? Ciò potrebbe interferire con il test.
Michael Hampton,

@MichaelHampton Sono abbastanza sicuro che Linode non lo faccia.
SEE

Puoi pubblicare il grafico di rete dal pannello di controllo di Linode? Quanta larghezza di banda sta effettivamente eseguendo questo test?
SEE

Ho fatto qualche indagine in più e ho aggiornato il post originale con molte più informazioni. Ho anche confermato con Linode che non eseguono la mitigazione DDOS, sebbene ciò non significhi necessariamente che un provider di rete tra il servizio di test del carico e Linode non lo stia facendo. Grazie!
Erik Swan,

1
C'è un motivo per cui hai impostato solo net.core.netdev_max_backlogfino al 2000? Diversi esempi che ho visto hanno un ordine di grandezza superiore per le connessioni gigabit (e 10Gig).
Moshe Katz,

Risposte:


1

Potrebbe esserci un numero qualsiasi di origini dei ripristini di connessione. Il tester di carico potrebbe essere fuori dalle porte effimere disponibili da cui avviare una connessione, un dispositivo lungo il percorso (come un firewall che esegue NAT) potrebbe avere il suo pool NAT esaurito e non è in grado di fornire una porta di origine per la connessione, c'è un bilanciamento del carico o un firewall alla tua estremità che potrebbe aver raggiunto un limite di connessione? E se si esegue il NAT di origine sul traffico in entrata, potrebbe verificarsi anche l'esaurimento delle porte.

Uno avrebbe davvero bisogno di un file pcap da entrambe le estremità. Ciò che si desidera cercare è se un tentativo di connessione viene inviato ma non raggiunge mai il server ma appare comunque come se fosse stato ripristinato dal server. In tal caso, qualcosa lungo la linea ha dovuto ripristinare la connessione. L'esaurimento del pool NAT è una fonte comune di questo tipo di problemi.

Inoltre, netstat -st potrebbe darti alcune informazioni aggiuntive.


1

Alcune idee da provare, basate sulle mie recenti esperienze di ottimizzazione simili. Con riferimenti:

Dici che è un file di testo statico. Nel caso in cui sia in corso un'elaborazione a monte, apparentemente i socket di dominio migliorano il throughput TCP su una connessione basata su porta TC:

https://rtcamp.com/tutorials/php/fpm-sysctl-tweaking/ https://engineering.gosquared.com/optimising-nginx-node-js-and-networking-for-heavy-workloads

Indipendentemente dalla terminazione a monte:

Abilita multi_accept e tcp_nodelay: http://tweaked.io/guide/nginx/

Disabilita avvio lento TCP: /programming/17015611/disable-tcp-slow-start http://www.cdnplanet.com/blog/tune-tcp-initcwnd-for-optimum-performance/

Ottimizza la finestra di congestione TCP (initcwnd): http://www.nateware.com/linux-network-tuning-for-2013.html


1

Per impostare il numero massimo di file aperti (se ciò sta causando il problema) è necessario aggiungere "fs.file-max = 64000" a /etc/sysctl.conf


0

Per favore, guarda quante porte sono in TIME_WAITstato usando il comando netstat -patunl| grep TIME | wc -le cambia net.ipv4.tcp_tw_reusein 1.


Come guarderei quante porte ci sono nello TIME_WAITstato?
Erik Swan,

Utilizzando netstato ss. Ho aggiornato la mia risposta con il comando completo!
fgbreel

Ho rieseguito il test e watch -n 1 'sudo netstat -patunl | grep TIME | wc -l'restituisce 0 durante l'intero test. Sono certo che i ripristini arriveranno a seguito della mitigazione DDOS da parte di qualcuno tra il tester di carico e il mio server, in base alla mia analisi del file PCAP che ho pubblicato sopra, ma se qualcuno potesse confermare sarebbe fantastico!
Erik Swan,
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.