...

Pianificazione della capacità di PHP-FPM: calcolo dei worker, della RAM e delle richieste simultanee

Per una pianificazione razionale della capacità di PHP-FPM, devi innanzitutto calcolare quanti worker possono essere contenuti nella RAM disponibile. A parte questo, devi stimare quanti worker siano necessari per gestire il traffico effettivamente in arrivo nel pool. pm.max_children limita il numero di worker disponibili contemporaneamente per ogni pool, ma non rappresenta né un numero di visitatori né un valore diretto di throughput. Anche la CPU, il database e i picchi di carico determinano quale impostazione sia sostenibile in fase operativa.

Cosa limita un worker PHP-FPM

PHP-FPM gestisce i processi PHP in pool. Un Lavoratore elabora una richiesta alla volta; l'impostazione del pool pm.max_children limita il numero di worker disponibili contemporaneamente e, di conseguenza, il numero di richieste PHP elaborate contemporaneamente da questo pool. In presenza di più pool, il limite si applica al singolo pool in questione e non automaticamente all’intero server.

Questo numero non corrisponde né al numero di visitatori registrati né a un valore diretto delle richieste al secondo. Un visitatore può generare più richieste, mentre un utente registrato non occupa un worker tra un’azione e l’altra. Al contrario, una singola richiesta lenta può occupare un worker più a lungo rispetto a diverse richieste brevi consecutive.

Inoltre, non tutte le richieste di pagina raggiungono PHP-FPM. Se il server web fornisce direttamente un file statico o se una cache a monte risponde completamente a una richiesta, a seconda dell’architettura non è necessario alcun worker PHP. I cache miss, gli utenti che hanno effettuato l’accesso e le pagine di amministrazione, invece, possono comunque generare richieste PHP e aumentare temporaneamente il carico.

Per la pianificazione della capacità sono quindi fondamentali due questioni distinte: quanti worker, compresa una riserva, possono essere contenuti nella RAM disponibile? E quanti worker sono effettivamente necessari per gestire il traffico in arrivo nel pool, in modo che le richieste non rimangano in attesa per un tempo eccessivo? Un valore elevato per pm.max_children Non risponde da sola a nessuna di queste domande.

Anche se la memoria disponibile è sufficiente, la CPU, il database o i servizi esterni possono limitare la capacità effettiva. I worker aggiuntivi consentono sì di eseguire più operazioni PHP in parallelo, ma allo stesso tempo possono aumentare il carico su un servizio già lento. Il valore del pool rappresenta quindi un limite operativo e non una garanzia di prestazioni.

Comprendere il gestore dei processi e la coda

Il sito Responsabile dei processi definisce quando PHP-FPM mette a disposizione i worker. In caso di static il numero di processi in sospeso corrisponde al valore di pm.max_children. Ciò rende il numero dei processi facilmente pianificabile, ma impegna comunque delle risorse anche in caso di basso carico di lavoro. Il limite massimo deve comunque essere compatibile con lo spazio di memoria disponibile.

All'indirizzo dynamic FPM regola il numero di processi: vengono inoltre impostati il numero iniziale e il numero minimo e massimo di worker liberi. In caso di ondemand I worker vengono creati solo quando necessario e vengono terminati dopo un periodo di inattività configurato. Ciò può consentire di risparmiare risorse nei pool utilizzati raramente; tuttavia, in caso di un picco improvviso di carico, è necessario creare innanzitutto nuova capacità di elaborazione.

Confronto tra i gestori di processo
ModalitàImpostazioni importantiImpiego e valutazione
staticopm.max_childrenNumero fisso di lavoratori; facile da pianificare, ma impiego di risorse inattive.
dinamicopm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_serversAdeguamento alle mutevoli esigenze; è necessario coordinare i worker liberi e quelli in fase di avvio.
a richiestapm.max_children, pm.process_idle_timeoutWorker solo quando necessario; consente di risparmiare risorse nei pool utilizzati raramente; in caso di aumento del carico di lavoro occorre tenere conto dell’avvio dei processi.

Se tutti i worker sono occupati, le richieste successive possono essere inserite nella Coda degli ascoltatori attendere un processo libero. Lo stato FPM mostra, tra le altre cose, la lunghezza attuale e quella massima della coda. Tuttavia, un singolo valore massimo elevato non indica se il pool sia attualmente sovraccarico; per stabilirlo è necessario un riferimento temporale.

Una coda più lunga non crea worker aggiuntivi né accelera un database lento. Può accogliere temporaneamente le richieste, ma si limita a spostare il tempo di attesa prima dell’elaborazione PHP. Per la scelta del gestore di processi sono quindi importanti sia l’andamento tipico del carico che le conseguenze dei brevi picchi.

Classificare correttamente la memoria del worker

Il fabbisogno di memoria di un worker non può essere determinato in modo affidabile solo sulla base di un limite di configurazione PHP. Ai fini della pianificazione, i dati relativi ai processi in condizioni di carico adeguate risultano più utili. A tal proposito, è importante distinguere se si sta esaminando la memoria residente di un singolo processo o se si intende valutare il consumo di un intero gruppo di worker PHP-FPM.

RSS descrive la memoria residente di un processo. Se più worker utilizzano le stesse pagine di memoria, queste possono essere incluse nei rispettivi RSS. Sommando i valori RSS di tutti i worker, le pagine condivise potrebbero apparire più volte; la somma non fornisce quindi un’indicazione precisa della memoria fisica occupata in comune.

PSS distribuisce le pagine condivise in proporzione tra i processi coinvolti. La somma dei valori PSS di un gruppo di processi è quindi spesso più utile per la pianificazione della memoria rispetto alla somma dei valori RSS. Tuttavia, rimane un’istantanea: se cambia il numero dei processi che condividono le pagine, cambiano anche le rispettive quote.

Considera più worker sia per richieste tipiche che per quelle che richiedono un uso intensivo della memoria. Un processo appena avviato o una singola media possono sottostimare il fabbisogno futuro. Il PSS complessivo del pool con diversi numeri di worker e condizioni di carico aiuta a ricavare un valore approssimativo prudenziale; un'estrapolazione a un numero maggiore di worker rimane incerta a causa della variabilità delle quote comuni e private.

Il PHP-memory_limit non costituisce un dato affidabile relativo alla memoria totale del sistema operativo di un processo FPM e non sostituisce tale osservazione. La memoria condivisa, ad esempio tramite OPcache, non dovrebbe essere detratta una seconda volta dal budget in modo generalizzato, se è già inclusa proporzionalmente nel PSS del pool utilizzato. Occorre comunque tenere conto degli altri servizi e di una riserva.

Calcolare il budget di RAM e il numero di worker

Il punto di partenza è la RAM effettivamente disponibile: su un host, la memoria utilizzabile per i servizi; nel container, il limite effettivo di memoria. Da questa quantità va sottratto il fabbisogno del sistema operativo, del server web, di un eventuale database locale e di altri servizi. Nel calcolo vanno inclusi anche altri pool FPM e una riserva per il consumo variabile.

Immagine simbolica generata dall'intelligenza artificiale che raffigura un modulo RAM smontato su un tappetino antistatico da officina.
Immagine simbolica generata dall'IA: la RAM disponibile limita il budget per i pool PHP-FPM.

La quota restante è quella Budget per la piscina. Per ottenere una stima del numero di worker, osserva la somma PSS dei worker del pool in presenza di diversi numeri di processi e condizioni di carico. Prendi in considerazione sia le richieste tipiche sia gli endpoint che richiedono un uso intensivo della memoria. Dividi la somma corrispondente per il numero di worker considerato e ricava un valore approssimativo prudente sulla base di diverse osservazioni.

Il calcolo che segue è un esempio illustrativo, non una misurazione. I valori ipotizzati servono solo a illustrare il procedimento di calcolo; non costituiscono una raccomandazione per una specifica applicazione. Il risultato viene arrotondato al numero intero di worker più vicino.

Pianificazione illustrativa della RAM per un singolo pool
Fase di calcoloAccettazioneClassificazione
Limite effettivo della RAM4.096 MiBLimite dell'host o del container nell'esempio
Altri servizi, pool e riserva2.048 MiBDetrazione concordata congiuntamente
Bilancio per il pool in esame2.048 MiB4.096 meno 2.048 MiB
Valore approssimativo PSS per ogni lavoratore80 MiBValore di pianificazione prudenziale adottato
Limite teorico della RAM25 lavoratori2.048 diviso per 80, arrotondato per difetto

I 25 worker non garantiscono un'allocazione sicura. PSS distribuisce le pagine condivise in modo proporzionale e varia in base al numero di processi che condividono tali pagine. Anche un diverso mix di richieste può modificare il fabbisogno di memoria privata; l'estimazione dovrebbe quindi essere verificata rispetto al consumo totale osservato e al limite disponibile.

Se la memoria condivisa, come l’OPcache, è già inclusa proporzionalmente nella somma PSS utilizzata, non devi dedurla nuovamente in modo forfettario come voce aggiuntiva completa. Prevedi comunque una riserva per le quote di memoria che non rientrano nella tua analisi. Soprattutto in caso di limite di container, ciò che conta in definitiva è il consumo di tutti i processi entro tale limite, non solo la somma stimata dei worker.

Un worker appena avviato, di per sé, non è un dato sufficientemente significativo: potrebbe non aver ancora elaborato alcuna richiesta complessa. Confronta quindi diversi momenti e registra quali endpoint e quanti worker erano coinvolti in ciascuno di essi. In questo modo è possibile verificare se il valore approssimativo scelto regge anche in condizioni operative meno favorevoli, ma realistiche.

Stimare il numero di worker necessari in base alle richieste

Il calcolo della RAM indica il numero previsto di worker che possono essere ospitati. Per determinare il fabbisogno, occorre invece considerare quante richieste PHP arrivano effettivamente nel pool in questione e per quanto tempo occupano un worker. Come prima approssimazione vale la seguente formula: numero medio di worker occupati contemporaneamente pari al numero di richieste PHP al secondo moltiplicato per il tempo medio di occupazione di un worker in secondi.

Esempio di calcolo illustrativo, non basato su misurazioni: ipotizzando 20 richieste PHP al secondo e un tempo medio di elaborazione di 0,25 secondi, in media sono attivi cinque worker. Si tratta di una media relativa al periodo considerato. Ciò non significa né che siano sempre esattamente cinque i processi attivi, né che cinque siano sufficienti come limite del pool per brevi picchi di carico.

Per il conteggio delle richieste non devi considerare tutte le visualizzazioni di pagina senza verificarle. Se una cache fornisce molte risposte senza ricorrere a PHP, tali risultati non gravano sul pool. Al contrario, i cache miss, i visitatori che hanno effettuato l'accesso e gli accessi amministrativi possono talvolta generare un carico di lavoro PHP maggiore di quanto lascerebbe supporre una media calcolata sull'arco dell'intera giornata.

Il sito Orario di presenza dei lavoratori comprende anche i tempi di attesa durante l'elaborazione, ad esempio in attesa di una risposta da un database o da un servizio esterno. Non è automaticamente equiparabile al tempo di risposta visibile nel browser. Secondo fastcgi_finish_request() PHP potrebbe aver già completato la risposta al client e continuare comunque a eseguire altre operazioni nel worker.

Per garantire tempi di attesa accettabili, è necessario un margine al di sopra del carico medio. La sua entità dipende, tra l’altro, dalle fluttuazioni del carico, dagli endpoint lenti e dall’obiettivo di tempo di risposta desiderato. Moltiplicare il numero di richieste di picco al secondo per un percentile di latenza elevato può costituire una verifica prudenziale dello scenario, ma non rappresenta una previsione precisa delle code.

Considera quindi separatamente diversi intervalli di tempo: un breve picco di attività e un traffico notturno più tranquillo possono dare lo stesso valore medio giornaliero di un funzionamento più uniforme, ma comportano esigenze diverse. Se il tempo di occupazione aumenta a causa di un backend lento, a parità di tasso di arrivo cresce anche il numero medio di worker occupati. Il fabbisogno non è quindi una caratteristica esclusiva dell’afflusso di visitatori.

Derivare le impostazioni della pool dalla pianificazione

Confronta ora il limite massimo basato sulla RAM con il fabbisogno stimato, compreso un margine di sicurezza. Se il fabbisogno rientra in tale limite, scegli un valore iniziale prudente per pm.max_children, che non deve necessariamente sfruttare tutto il budget. Nell'esempio illustrativo, 25 sarebbe il limite teorico della RAM, ma non necessariamente l'impostazione più adatta; la CPU e il backend potrebbero già imporre dei limiti prima di raggiungere tale valore.

Se il fabbisogno stimato supera il limite della RAM, impostare un limite più alto non risolve il problema: potrebbe mettere sotto pressione l’host o il container in termini di memoria. Al contrario, un limite troppo basso può causare ritardi nelle richieste. In questo caso, ottimizza ad esempio il tempo di esecuzione o l’utilizzo della cache e verifica se sono necessarie risorse aggiuntive o una limitazione del carico in entrata.

All'indirizzo dinamico Oltre al limite massimo, devi impostare il numero iniziale, nonché il numero minimo e massimo di worker liberi. I valori iniziali e di riserva dovrebbero essere adeguati al carico previsto e rimanere entro il limite massimo. Una capacità di riserva insufficiente può comportare un fabbisogno aggiuntivo di avvio in caso di carico improvviso; al contrario, un numero elevato e prolungato di processi liberi consuma risorse.

All'indirizzo a richiesta I worker vengono creati solo quando necessario; il tempo di inattività fino al loro termine viene impostato separatamente. Ciò può essere utile per i pool utilizzati raramente, ma richiede particolare attenzione in caso di rapidi aumenti del carico. Anche in questo caso, limita pm.max_children il numero di worker del pool disponibili contemporaneamente.

Più siti web ospitati sullo stesso server non ricevono, indipendentemente l'uno dall'altro, l'intera RAM libera a disposizione. È necessario pianificare i loro possibili limiti massimi di pool insieme agli altri servizi e alla riserva. Un limite globale dei processi FPM, se configurato, può avere un effetto aggiuntivo, ma non sostituisce né i singoli budget dei pool né la verifica della capacità della CPU e del database.

Dopo aver apportato delle modifiche, verifica l'effettivo carico di lavoro e i tempi di attesa su periodi di tempo adeguati, invece di considerare il valore iniziale come definitivo. Nel caso dell’hosting gestito, i dati di processo o le impostazioni del pool potrebbero non essere direttamente accessibili; in tal caso, utilizza le metriche e le opzioni rese disponibili dal provider. Le impostazioni disponibili dipendono inoltre dalla versione di PHP e dall’ambiente operativo.

Monitoraggio dello stato dell'FPM e della memoria

La pagina di stato dell'FPM mostra se i worker pianificati sono sufficienti in condizioni di carico reale. Proteggi l'endpoint di stato non accessibile al pubblico: potrebbe rivelare informazioni sensibili relative alle richieste e alle risorse. Un listener di stato configurato separatamente può rimanere accessibile anche quando il pool principale è sovraccarico; verifica la sua disponibilità e configurazione per la tua versione di PHP e la configurazione del server web.

Analizzare i valori di stato FPM nel contesto temporale
Valore di statoClassificazioneDomanda di approfondimento
processi attivi / processi inattiviLavoratori attualmente assunti e lavoratori autonomiDurante i picchi di carico rimangono disponibili dei worker liberi?
coda di ascolto / coda di ascolto massimaLunghezza attuale e massima registrata finora della codaLa coda si allunga quando le risposte sono lente?
bambini massimi raggiuntiContatore per il raggiungimento del limite dei worker nelle modalità "dynamic" o "ondemand"Il contatore aumenta nel periodo in esame?
richieste lenteContatore delle richieste lenteQuesto aumento coincide con tempi di risposta più lunghi?

Considera i valori come serie temporali insieme al volume delle richieste e ai tempi di risposta. Un vecchio valore massimo della coda non è indice di un sovraccarico attuale; allo stesso modo, nel caso dei contatori, il loro aumento dall’ultima osservazione è più significativo del semplice valore totale. Tieni conto dell’avvio del pool o dei riavvii, che modificano il periodo di riferimento.

Illustrazione generata dall'intelligenza artificiale raffigurante due strisce di carta con gruppi di punti attuali e precedenti.
Illustrazione generata dall'intelligenza artificiale: i valori attuali e i massimi storici devono essere contestualizzati nel tempo.

Per un worker FPM noto, su un sistema Linux con interfaccia proc disponibile è possibile recuperare in lettura i valori di memoria aggregati. Sostituisci PID tramite l'ID effettivo del processo; è necessario disporre dei diritti di accesso corrispondenti. Ripeti l'osservazione per più worker e condizioni di carico, invece di dedurre una dimensione fissa del pool da un singolo processo.

Terminale
cat /proc/PID/smaps_rollup

Analisi delle richieste lente e delle code

Un negozio online può mostrare molti worker attivi, anche se l'esecuzione di PHP in sé non costituisce il collo di bottiglia originario. Se le richieste rimangono in attesa a causa di query lente sul database, i worker rimangono bloccati nel frattempo. Se arrivano ulteriori richieste, la coda del listener può allungarsi e il tempo di risposta aumentare, anche se la CPU dispone ancora di risorse disponibili.

In questa situazione, un limite più elevato per i worker potrebbe consentire l'invio simultaneo di un maggior numero di richieste al database. Ciò può causare il Stampa backend aumentare e allungare ulteriormente i tempi di attesa. Pertanto, prima di aumentare il limite, confronta l'andamento nel tempo del carico di FPM e della coda con il carico del database, le query lente e le chiamate a servizi esterni.

Lo "Slowlog" di FPM aiuta a individuare le chiamate PHP di lunga durata: per le richieste che superano una soglia configurata, FPM può registrare un backtrace. Questo mostra un punto di esecuzione e non costituisce un profilo completo dell'intera richiesta. I punti ricorrenti possono essere confrontati con la durata della richiesta e le metriche del backend; il Guida all'analisi dello slowlog di PHP-FPM come illustra l'analisi successiva.

Anche un timeout va distinto dalla capacità effettiva. In nginx, si indica fastcgi_read_timeout l'intervallo consentito tra due operazioni di lettura consecutive da parte del server FastCGI, non la durata complessiva della richiesta. Un valore più alto può consentire tempi di attesa più lunghi, ma non crea worker aggiuntivi né accelera il database.

Limiti di capacità e prossimi passi

Se la quantità di RAM disponibile non è sufficiente a soddisfare il fabbisogno stimato, è possibile aumentare l'impostazione per pm.max_children Non ignorare il conflitto di obiettivi: anche i processi aggiuntivi richiedono memoria. Verifica invece se è possibile ridurre il numero di richieste PHP o la durata del loro utilizzo da parte dei worker. La misura più opportuna dipende da dove si genera il carico osservato.

Un utilizzo più efficiente della cache può intercettare le richieste ripetute, mentre un’esecuzione più veloce di PHP e gli accessi al database liberano prima i worker. Le attività in background appropriate possono essere spostate fuori dal percorso diretto della richiesta; tuttavia, anche queste attività richiedono risorse proprie. Un limite di carico protegge il backend nei momenti di picco, ma può comportare che le richieste rimangano in attesa o vengano respinte.

Una maggiore quantità di RAM può consentire di aumentare il numero di worker, qualora la memoria rappresenti effettivamente il limite determinante. Se la CPU, il database o un servizio esterno sono già al limite della loro capacità, occorre tenere conto anche di questa. Una maggiore quantità di memoria, di per sé, non garantisce quindi né tempi di risposta più brevi né una maggiore produttività.

Se il fabbisogno di memoria dei singoli worker supera il loro ciclo di vita, è possibile pm.max_requests provvedere alla loro sostituzione periodica. Ciò può aiutare a gestire le perdite di memoria nelle librerie di terze parti, ma non ne risolve la causa. Dopo aver apportato una modifica, continua a monitorare la memoria del pool e il comportamento delle richieste, invece di considerare il meccanismo di riavvio come un sostituto della ricerca degli errori.

Per una scelta architettonica più ampia, il Confronto tra NGINX Unit e PHP-FPM Contesto: NGINX Unit è stato archiviato e non viene più aggiornato. Indipendentemente dall'architettura scelta, dovresti apportare le modifiche in base a serie temporali Verificare: in presenza di un volume di richieste simile, confrontare la coda, il carico di lavoro dei worker, la memoria e i tempi di risposta. In questo modo è possibile stabilire se una modifica abbia effettivamente risolto il collo di bottiglia o se lo abbia semplicemente spostato altrove.

Fonti e stato dell'arte

Stato della ricerca:

Aggiornamento della ricerca: 4 novembre 2026. Verificare la disponibilità dello Status Listener, dei dati di processo e delle impostazioni del pool per la versione di PHP e Linux in uso, nonché per l'ambiente di hosting.

https://www.php.net/install.fpm.configuration

https://www.php.net/fpm.status.php

https://docs.kernel.org/7.0/filesystems/proc.html

https://www.kernel.org/doc/html/v6.12/filesystems/proc.html

https://www.php.net/manual/de/install.fpm.php

https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html

Articoli attuali

CrowdSec vs. Fail2Ban: differenze nell'uso pratico

CrowdSec e Fail2Ban bloccano gli indirizzi IP sospetti, ma si differenziano per quanto riguarda il rilevamento, l'applicazione delle misure e il carico di lavoro operativo. Il confronto mostra quale soluzione sia più adatta a VPS, proxy e configurazioni distribuite.