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.