Risolvere l’Errore 24: Too many open files e come migliorare le prestazioni di Nginx.

Tabella dei Contenuti

L’errore Too many open files indica che il sistema ha raggiunto il limite massimo di file aperti contemporaneamente. Questo limite può essere impostato a livello di sistema operativo o per il singolo processo del server web Nginx.

Per risolvere questo problema, puoi provare i seguenti passaggi:

  • Verificare la configurazione del sistema
  • Aumentare il limite dei file aperti per il sistema
  • Aumentare il limite dei file aperti per Nginx
  • Monitorare e ottimizzare le risorse

Verificare la configurazione del sistema

La prima operazione è verificare l’attuale configurazione del sistema, per verificare il limite dei file aperti accedendo al nostro server via SSH digitiamo:

ulimit -n

Per esempio se il risultato che otteniamo è 1024, significa che il nostro limite è impostato a tale valore, che è molto basso per un server Web. Si tratta di un valore di default e molto conservativo.

Considerazioni generali

Determinare il valore ottimale di file contemporaneamente aperti (cioè il limite nofile) per un web server che esegue siti WordPress e PrestaShop dipende da diversi fattori, tra cui il numero di visitatori simultanei, la configurazione del server, l’uso di caching, e la complessità dei siti.

  • Tipologia di siti:
    • WordPress e PrestaShop sono entrambi abbastanza intensivi in termini di risorse, specialmente se hai molti plugin attivi o se gestisci un negozio online con un grande catalogo di prodotti e molte immagini.
    • I siti dinamici come questi tendono a richiedere più risorse, tra cui un numero maggiore di file aperti, rispetto ai siti statici.
  • Connessioni simultanee:
    • Un numero maggiore di visitatori simultanei richiede un limite più alto di file aperti. Ogni connessione può aprire più file: script PHP, file di configurazione, immagini, CSS, JavaScript, ecc.
  • Caching:
    • Implementare caching lato server (come Opcache per PHP) o lato client può ridurre la pressione sul server, ma il numero di file aperti può comunque essere significativo.

L’importanza del parametro worker_connections

Il parametro worker_connections in Nginx indica il numero massimo di connessioni simultanee che ciascun worker process (processo di lavoro) può gestire. Questo include tutte le connessioni attive, comprese quelle con i client e quelle ai server upstream. Tale parametro ha un impatto notevole sulla capacità di gestire più richieste contemporanee, di default è configurato a 1 in Plesk.

Dettagli su worker_connections

  • Connessioni simultanee: Rappresenta il numero totale di connessioni che un singolo worker process può gestire simultaneamente. Se hai, ad esempio, worker_connections 1024;, ciascun worker process può gestire fino a 1024 connessioni contemporaneamente.
  • Limite teorico: Il limite teorico massimo di connessioni che il server Nginx può gestire è dato da worker_processes * worker_connections. Quindi, se hai worker_processes 4; e worker_connections 1024;, il server può teoricamente gestire fino a 4096 connessioni simultanee.

Una buona pratica è impostare worker_processes al numero di core CPU disponibili.

Calcolo del limite ottimale

Supponiamo che tu abbia deciso di settare worker_processes in base al numero di CPU (ad esempio, 8 CPU), e che stimi che ogni processo worker di Nginx possa gestire circa 1000 connessioni simultanee.

Ogni connessione può utilizzare 2 o più file aperti (script PHP, file statici, connessioni a database, ecc.). Per sicurezza, supponiamo 4 file aperti per connessione:

Numero di file per connessione=4

File aperti per processo worker=1000×4=4000

Se hai 8 processi worker:

Totale file aperti=4000×8=32000

Valori Consigliati

  • Limite minimo: Se il tuo server ha un carico medio-basso (pochi visitatori simultanei), un limite di 1024 – 4096 file aperti potrebbe essere sufficiente.
  • Limite consigliato per carichi medio-alti: Per server con carichi più elevati o con molti visitatori simultanei, considera un limite tra 8192 – 65535.
  • Limite per server ad alto traffico: Se gestisci un server con molto traffico, o se esegui numerosi siti WordPress/PrestaShop, considera di aumentare il limite a 65535 – 262144.

Ecco una tabella riassuntiva che mostra i valori ottimali per ambienti con elevato traffico:

Numero di CPU worker_processes worker_rlimit_nofile worker_connections
4 4 262144 65536
8 8 262144 32768
12 12 262144 21845
16 16 262144 16384

Per siti WordPress e PrestaShop con traffico moderato-alto, un limite di 65535 file aperti è una configurazione sicura. Questi valori possono essere modificati in base alle specifiche necessità del tuo server, e monitorare regolarmente il carico e le performance del server ti aiuterà a determinare se sono necessarie ulteriori ottimizzazioni.

Quando ridurre worker_connections può essere utile

Ridurre worker_connections di una piccola percentuale può essere utile se si vuole evitare l’allocazione eccessiva di risorse, ma è essenziale bilanciare questa scelta con la consapevolezza del traffico e delle esigenze specifiche del server. Se il traffico previsto è alto, è meglio non ridurre troppo questo valore per evitare colli di bottiglia nelle prestazioni.

  • Carichi di lavoro prevedibili: Se conosci bene il traffico e sai che il tuo sito raramente raggiunge i limiti superiori di connessioni simultanee, puoi impostare un valore leggermente più basso per evitare di allocare risorse inutilmente.
  • Monitoraggio delle prestazioni: Se stai monitorando attivamente il server e hai strumenti per rilevare quando le connessioni iniziano a saturare, puoi permetterti di ridurre worker_connections e aumentarlo solo se necessario.
  • Margine di sicurezza: Se desideri lasciare un margine di sicurezza per eventuali picchi imprevisti o per evitare l’uso di tutte le risorse disponibili, ridurre leggermente worker_connections può essere una scelta prudente.

Esempio con riduzione del 10%

Numero di CPU worker_processes worker_rlimit_nofile worker_connections
4 4 262144 58982
8 8 262144 29491
12 12 262144 19660
16 16 262144 14745

Esempio configurazione per un server con 8 CPU core

Vediamo un esempio pratico di come impostare una configurazione per un server con 8 CPU

1. Applicare immediatamente i limiti dei file aperti

Modifica /etc/security/limits.conf

sudo nano /etc/security/limits.conf

Aggiungi le seguenti righe:

* soft nofile 262144
* hard nofile 262144

Dopo aver modificato /etc/security/limits.conf, puoi applicare i nuovi limiti alla sessione corrente utilizzando il comando ulimit.

Applica i nuovi limiti alla sessione corrente, per evitare il riavvio:

ulimit -Sn 262144
ulimit -Hn 262144

Apri il file di configurazione principale di Nginx:

sudo nano /etc/nginx/nginx.conf

2. Applicare immediatamente le modifiche a systemd

Per applicare le modifiche ai limiti dei file aperti senza riavviare il sistema, puoi ricaricare la configurazione di systemd e riavviare i servizi necessari.

Modifica i file di configurazione /etc/systemd/system.conf e /etc/systemd/user.conf

sudo nano /etc/systemd/system.conf
sudo nano /etc/systemd/user.conf

Aggiungi o modifica le seguenti righe:

DefaultLimitNOFILE=262144

Ricaricare la configurazione di systemd:

sudo systemctl daemon-reload

Riavvia Nginx per applicare i nuovi limiti:

sudo systemctl restart nginx

Verifica dei limiti

Dopo aver applicato le modifiche, verifica i nuovi limiti dei file aperti:

ulimit -Sn
ulimit -Hn

Verifica anche il limite dei file aperti per i processi Nginx:

Trova il PID di Nginx:

ps aux | grep nginx

Verifica il limite per uno dei PID di Nginx:

cat /proc/<PID>/limits | grep "Max open files"

Sostituisci <PID> con l’ID del processo di Nginx. Questo ti mostrerà il limite massimo di file aperti per il processo specificato.

Modifica della configurazione di Ngnix

Una volta configurati i nuovi limiti, modifichiamo la configurazione di Ngnix

Apri il file di configurazione principale di Nginx:

sudo nano /etc/nginx/nginx.conf

Rivediamo la configurazione come segue:

worker_processes  8;
worker_rlimit_nofile 262144;

events {
    worker_connections  32768;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server_tokens off;

    include /etc/nginx/conf.d/*.conf;
}

Verifica la configurazione di Nginx

sudo nginx -t

Se il test è riuscito, dovresti vedere qualcosa del genere:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Riavvia Nginx per applicare le modifiche:

sudo systemctl restart nginx

Monitoraggio della nuova configurazione

Dopo aver riavviato Nginx, monitora il server utilizzando strumenti come top, htop, netstat per assicurarti che tutto funzioni come previsto e che il server possa gestire un elevato numero di connessioni simultanee. Seguendo questi passaggi, puoi applicare le modifiche necessarie senza dover riavviare il sistema, garantendo che i nuovi limiti dei file aperti siano effettivamente utilizzati da Nginx e altri processi.

Possiamo anche programmare un load test attraverso l’utility di benchmark Siege.