Le richieste HTTP possono bloccarsi anche se la CPU, la RAM e la larghezza di banda sembrano aperte, perché i limiti, i filtri e le code invisibili entrano in vigore lungo l'intera catena. Spiego dove Confini come funzionano e quali impostazioni devo impostare per far sì che le richieste funzionino di nuovo senza problemi.
Punti centrali
Prima di entrare nel dettaglio, riassumerò le cause più importanti e indicherò quali sono i primi punti da esaminare. Questi punti coprono i tipici colli di bottiglia che portano alla congestione nonostante le risorse libere. Ho volutamente mantenuto l'elenco compatto in modo che possiate verificare immediatamente i punti di partenza. Il punto chiave è che ogni livello ha le sue regole che si applicano indipendentemente dalla CPU e dalla RAM. Se si conoscono queste regole, è possibile risolvere rapidamente molti tempi di attesa „inspiegabili“.
- Limiti dei lavoratoriTroppi processi/thread bloccano le nuove connessioni nonostante la CPU libera.
- Livello di sicurezzaI filtri WAF/web bloccano modelli, metodi o client, spesso senza un carico elevato.
- ConcorrenzaPHP-FPM, database e proxy limitano le sessioni simultanee.
- Keep-Alive/TimeoutLe connessioni lunghe occupano gli slot, le richieste finiscono in coda.
- Filtro clienteLe estensioni del browser bloccano le richieste prima che raggiungano il server.
Questi punti chiave sono spesso sufficienti per verificare il comportamento in modo mirato. Di seguito, vi mostrerò come ricavo misure specifiche da questi e Blocco in modo pulito.
Perché le richieste HTTP si bloccano nonostante le risorse libere
Una richiesta passa attraverso diversi livelli: Client, rete, filtro, server web, ambiente di runtime e database. Ogni livello porta con sé i propri Limiti che hanno effetto indipendentemente dalla CPU, dalla RAM o dalla larghezza di banda. Se gli slot dei lavoratori sono occupati o le regole sono attive, la richiesta attende in una coda o viene immediatamente annullata. Questo tempo di attesa spesso non appare affatto nei classici diagrammi delle risorse. È proprio questo che porta a pensare erroneamente che il server sia „vuoto“, anche se le richieste non vengono evase.
Livello di sicurezza: WAF, filtri e regole del provider
Molti blocchi avvengono prima ancora che l'applicazione sia in esecuzione. I firewall per applicazioni Web, gli IDS/IPS e i filtri lato provider riconoscono i modelli e li rallentano o li bloccano [1][5][9]. Parametri sospetti, protocolli obsoleti o combinazioni di metodi sono sufficienti a causare un blocco. Blocco di accendersi. Dal punto di vista dell'operatore, questo sembra un errore del server, ma la decisione viene presa „a monte“. Pertanto, controllo i log del WAF e prendo nota dell'ID della richiesta, dell'IP, dell'ora e del codice di stato. Con questi dati è possibile identificare la regola e modificarla in modo mirato senza compromettere la sicurezza.
Lato client: estensioni del browser e blocchi locali
Non tutte le richieste raggiungono il server. Adblocker, password manager e script blocker bloccano già gli URL nel browser; i DevTools mostrano quindi „Requests to the Server Have Been Blocked by an Extension“ [3][7]. Eseguo il test in una finestra privata, disattivo le estensioni e verifico se le Richiesta è stato inviato. È anche utile per controllare le priorità nel front-end, ad esempio con una soluzione pulita Priorità delle richieste per le risorse critiche. In questo modo si evita che chiamate di terzi non critiche ritardino percorsi importanti.
Metodo di comprensione e instradamento: 405, 403, 429
Un 405 „Metodo non consentito“ indica chiaramente che il server riconosce la risorsa ma non consente il metodo utilizzato [5]. Allo stesso modo, 403 indica filtri o diritti e 429 limitazioni di velocità attive. Nei log, posso riconoscere rapidamente se una regola globale consente metodi come INSERIRE o DELETE o se un endpoint non è mai stato implementato. A quel punto, modifico l'instradamento, il controllore o la regola WAF. In questo modo, il presunto „blocco“ si dissolve in una correzione pulita dei metodi e dei percorsi.
Architettura del server web e limiti dei lavoratori
Apache, NGINX, LiteSpeed e OpenLiteSpeed gestiscono le connessioni in modo diverso [4]. I fattori decisivi sono il numero di processi worker, i thread e il modo in cui i socket keep-alive occupano gli slot. Se tutti i worker sono occupati da connessioni lunghe, le nuove richieste si spostano su un Coda, anche se la CPU e la RAM sembrano libere. Analizzo quindi gli stati delle connessioni e regolo i lavoratori, i backlog e i tempi di keep-alive. Le conoscenze di base sulle code sono utili, ad esempio per quanto riguarda l'argomento Accodamento server e la latenza.
| strato | Limite pertinente | Sintomo tipico | Nota diagnostica |
|---|---|---|---|
| Server web | Numero di lavoratori/thread | Code, 503 sotto carico | Moduli di stato, per controllare lo stato delle connessioni |
| PHP-FPM/FastCGI | max_figli / pm | Richieste sospese, elevato tempo al primo byte | Registri FPM, registro lento, numero di processi |
| Banca dati | max_connessioni | Errore „Troppe connessioni“ | SHOW PROCESSLIST, picchi di connessione |
| WAF/Filtro | Firme, metodi | 403/405, messaggi del modulo non funzionanti | Registri WAF, ID di risposta alle regole |
| Bilanciatore di carico | Limite di connessione per backend | Tempi di risposta incoerenti | Statistiche LB, Salute Backend |
Concorrenza in PHP-FPM, database e proxy
L'elaborazione concorrente spesso esplode prima nell'ambiente di runtime. Se tutti i worker di PHP FPM sono occupati, non c'è nessuno slot disponibile per i nuovi script; le richieste attendono anche se il server di PHP FPM non è stato ancora attivato. CPU non funziona quasi mai. La situazione è simile per i database con max_connections o per i proxy con limiti di connessione per backend. Prima di aumentare i limiti, ottimizzo la durata delle singole richieste. In questo modo, accorcio il tempo del documento per slot e riduco la probabilità che le code crescano.
Backend lenti e blocco della sessione PHP
Le lunghe interrogazioni di database, le API esterne o l'I/O dei file bloccano i lavoratori molto più a lungo. Il blocco della sessione può anche rallentare intere catene, come i login di WordPress o i carrelli della spesa. Verifico se le richieste parallele allo stesso ID di sessione vengono eseguite consecutivamente invece che simultaneamente. In tal caso, mi affido a uno sblocco mirato, riduco gli accessi critici in scrittura e seguo le istruzioni collaudate del sito web Blocco della sessione PHP. Questo mi permette di liberare più rapidamente gli slot e di ridurre le Tempi di attesa percepibile.
Timeout, keep-alive e strategie di connessione
I tempi di keep-alive troppo lunghi impegnano le risorse, mentre quelli troppo brevi generano handshake e latenza. Scelgo valori che corrispondono al profilo di traffico e imposto limiti per i timeout di header, body e backend. È importante impostare i timeout non solo a livello di Server web ma standardizzato lungo la catena: proxy, app, database. Impedisco anche il blocco delle inattività attraverso impostazioni HTTP/2/HTTP/3 più precise e la definizione delle priorità. In questo modo si mantengono disponibili gli slot senza che i clienti debbano continuamente riconnettersi.
Modelli di hosting: Condivisi, VPS, Dedicati
L'hosting condiviso imposta filtri precoci e quote rigide in modo che la piattaforma rimanga equa [1]. Sui VPS, i fornitori isolano la CPU e la RAM, ma mantengono limiti per l'I/O, la rete o la sicurezza; le differenze in termini di prestazioni e monitoraggio sono evidenti [10]. Sui server dedicati, mi assumo la piena responsabilità della configurazione del server web, del database e del WAF. I confronti mostrano che i moderni stack con HTTP/3, NVMe e protezione DDoS offrono chiari vantaggi [2][6][11][8]. Coloro che necessitano di un elevato parallelismo possono beneficiare di una documentazione chiara e precisa Confini e supporto, che aiuta le unità di regole.
Analisi sistematica: passo dopo passo
Inizio dalla fonte: DevTools sta davvero inviando la richiesta o è un'estensione [3][7] a bloccarla? Poi guardo i codici di stato: 403/405/429/503 forniscono forti indicazioni su filtri, metodi o capacità [5]. Allo stesso tempo, controllo i log del server web, dell'app e del WAF per trovare schemi e firme ricorrenti [1][9]. Verifico poi il numero di lavoratori, i parametri FPM, le connessioni keep-alive e al database e aumento i limiti su base di prova con punti di misurazione prima e dopo. Infine, simulo il carico, osservo i colli di bottiglia in tempo reale e verifico che il Code strizzacervelli.
Le migliori pratiche contro i blocchi
Formulo obiettivi di concorrenza per ogni livello e stabilisco dei limiti in modo da attutire i picchi di carico. Il server web deve corrispondere al modello di traffico; i benchmark aiutano nella scelta e nella configurazione [4]. Ottimizzo i backend innanzitutto dal punto di vista logico: query più veloci, transazioni più brevi, meno sezioni seriali. Mantengo le regole di sicurezza sufficientemente rigide contro gli attacchi, ma con eccezioni per quelli legittimi. Campione. Il monitoraggio non si limita a CPU/RAM: osservo le connessioni, le code, i tempi di risposta e i codici di errore in modo che i colli di bottiglia rimangano visibili [6][11].
Note pratiche: blocco delle richieste di hosting
Negli ambienti condivisi, i blocchi spesso finiscono prima dello spazio web effettivo; il supporto ha quindi bisogno di dati di richiesta specifici per regolare le regole [1]. Sui VPS, la scala è graduale: più lavoratori, valori di keep-alive più appropriati e un monitoraggio più attento del database [10]. Sul mio hardware, decido il bilanciamento del carico, le regole WAF e i limiti per backend. I progetti con accesso altamente parallelo traggono vantaggio da una configurazione HTTP/2/HTTP/3 pulita e da riserve chiare per Suggerimenti. Se prevedete una crescita, pianificate il passaggio a tariffe più potenti all'inizio e risparmiate molti sforzi di messa a punto in seguito [2][6][10][11].
Limiti della rete e del kernel: backlog, porte e descrittori
Oltre al server web e all'applicazione, il kernel limita il numero di connessioni che possono arrivare, essere stabilite e gestite contemporaneamente. Per prima cosa controllo il Elenco arretratiAnche se il server web ha molti worker, la coda di accettazione può essere breve. L'interazione tra l'applicazione (listen backlog), il kernel (somaxconn) e il SYN backlog (tcp_max_syn_backlog) determina se le connessioni rimangono nella coda o vengono scartate. I sintomi sono un aumento dei tempi di connessione e delle ritrasmissioni, con un basso utilizzo della CPU. Confronto i valori e misuro l'utilizzo effettivo delle code per evitare cadute.
Un altro classico è il tavolo conntrack per le configurazioni NAT/firewall. Se è pieno, le connessioni scompaiono „senza lasciare traccia“; l'applicazione non vede mai una richiesta. Lo riconosco dai messaggi nel log di sistema e dai timeout improvvisi durante i picchi di carico. Le contromisure sono: dimensioni adeguate della tabella, timeout di inattività realistici per i protocolli, meno percorsi NAT non necessari e keep-alive efficienti che riutilizzino le connessioni in modo sensato.
Verifico anche il numero di aperture Descrittori di file (ulimit -n). Se molti socket e file simultanei raggiungono i limiti restrittivi, Accept fallisce („troppi file aperti“) e le nuove richieste si accumulano davanti ad esso. La soluzione è di solito banale: impostare i limiti di nofile per il server web, il proxy e il database a un livello sano, in modo persistente, non solo interattivo.
In configurazioni fortemente parallele, osservo il Intervallo di porte effimere e TIME_WAIT-Stati. Soprattutto dietro i gateway NAT, le porte di origine disponibili si esauriscono quando si stabiliscono in massa connessioni brevi. Per questo motivo mi affido al riutilizzo delle connessioni (keep-alive, HTTP/2/3), riduco le connessioni inutili di breve durata e metto a punto con attenzione la gestione di TIME_WAIT senza rischiare la stabilità. Il risultato: meno esaurimento delle porte e tempi di connessione più stabili sotto carico.
Sulla scheda di rete, controllo la lunghezza delle code, le impostazioni di offloading e la distribuzione degli IRQ. Interruzioni distribuite in modo non uniforme o code sovraccariche generano picchi di latenza che non si notano nei log dell'applicazione. Con un bilanciamento bilanciato degli IRQ e impostazioni ragionevoli di Qdisc (parola chiave Bufferbloat), riduco la latenza senza limitare la larghezza di banda.
HTTP/2 e HTTP/3: utilizzare correttamente il multiplexing
Il multiplexing risolve molti problemi, ma comporta nuovi limiti: Numero massimo di flussi, La finestra di controllo del flusso e i timeout di inattività si applicano a ogni connessione. Se il valore dei flussi simultanei è troppo basso, le nuove richieste si „bloccano“ anche se la connessione TCP o QUIC è stabilita. Pertanto, verifico quante risorse critiche devono essere caricate in parallelo e regolo attentamente i limiti dei flussi. Allo stesso tempo, faccio attenzione a un valore ragionevole di Controllo del flusso-in modo che le risposte di grandi dimensioni non siano limitate.
Il multiplexer HTTP/2 su TCP può soffrire del blocco della linea di testa in caso di perdita di pacchetti; HTTP/3 su QUIC lo evita, ma richiede impostazioni TLS/ALPN pulite e regole di gestione del percorso stabili. Io provo entrambi i percorsi e seleziono i protocolli che corrispondono al profilo di traffico. Importante: non fidatevi ciecamente della prioritizzazione: i browser e i server la interpretano in modo diverso. Mi concentro sui percorsi critici e verifico che le priorità funzionino effettivamente e che gli slot non siano occupati da flussi secondari di lunga durata.
CORS, voli preliminari e limiti testa/corpo
Non tutti gli errori 4xx provengono dal server. Reati CORS si verificano nel browser e vengono visualizzati nella console, non nel log degli accessi. Verifico se le richieste di preflight (OPZIONI) vengono risposte correttamente e se i WAF/proxy consentono questo metodo. Se mancano intestazioni come Access-Control-Allow-Methods/-Headers, il browser „blocca“ la risposta, senza alcun carico sul server.
Un altro collo di bottiglia: Dimensioni dell'intestazione e dei cookie. Cookie troppo grandi, molte intestazioni Vary o linee di referer di grandi dimensioni portano a errori 431 o a cadute silenziose a causa dei limiti del buffer. Limito la zavorra dei cookie, consolido le intestazioni e imposto le dimensioni del buffer in modo coerente lungo la catena. Per i caricamenti, faccio attenzione ai limiti del corpo, alla gestione di 100-continue e alla coerenza delle dimensioni del buffer lungo la catena. Codifica chunked-Supporto per tutti i proxy. Se i limiti di body e upload non corrispondono, i client attendono un rilascio che non arriva mai - le richieste sembrano „bloccarsi“.
DNS e TLS: gli handshake come latenza nascosta
La risoluzione DNS e la negoziazione TLS sono frequenti punti oscuri. Catene CNAME multiple, resolver lenti o mancata corrispondenza IPv6/IPv4 prolungano il tempo di avvio senza utilizzare la CPU. Riduco i salti DNS non necessari, imposto TTL ragionevoli e assicuro percorsi veloci ai resolver. Sul lato TLS, controllo le catene di certificati, le suite di cifratura attivate, lo stapling OCSP e la ripresa della sessione. Un handshake ALPN pulito impedisce i downgrade a HTTP/1.1, che mettono a dura prova gli slot di keep-alive. Risultato: un time-to-first-byte più breve e un parallelismo più stabile, soprattutto sulle reti mobili.
CDN/Edge: caching, limiti di velocità e reputazione IP
Tra il cliente e l'origine, i CDN, i reverse proxy e i sistemi di protezione DDoS decidono su Cunicolo e throttle. Verifico se le rotte critiche sono memorizzate nella cache correttamente (stale-while-revalidate, stale-if-error) e se le cache negative trattengono gli errori più a lungo del necessario. I limiti di velocità, la gestione dei bot e la reputazione dell'IP possono attenuare il traffico legittimo, soprattutto in caso di reti condivise o di accesso massiccio all'API. Segmento il traffico (per esempio, API o asset), definisco chiavi di cache chiare e disattivo le regole in modo selettivo per i client affidabili. In questo modo si alleggerisce il carico su Origin e si evita che le code della CDN crescano mentre il server sembra „sottoutilizzato“.
Contenitori e orchestrazione: cgroups, Ingress e conntrack
In contenitori applicare limiti del cgroup per CPU, RAM, pid e file. Una quota di CPU troppo stretta porta al throttling: i processi attendono il tempo della CPU anche se l'host è libero. Controllo le quote e mi assicuro che i pod ingress/proxy abbiano sufficienti descrittori di file e buffer. In Kubernetes, controllo i timeout in ingresso, le sonde di prontezza/lività e le implementazioni dei servizi (IPVS), perché sonde o timeout difettosi generano latenza a zig zag e riavvii non necessari.
Un collo di bottiglia spesso trascurato è la Capacità NAT/traccia per nodo. Molte connessioni di breve durata (ad esempio, l'uscita verso API esterne) riempiono la tabella di conntrack, quindi le richieste „scompaiono“ nella rete. Ridimensiono la tabella, imposto timeout realistici e raggruppo le chiamate esterne in modo che vengano create meno nuove connessioni. Pianifico i PodDisruptionBudget, i rolling update e il ridimensionamento dell'HPA in modo che non venga sottratta capacità allo scheduler nei momenti di picco, altrimenti si formano code, anche se l'applicazione non è in grado di funzionare. teoricamente avrebbe avuto un numero sufficiente di lavoratori.
Osservabilità: correlazione, tracciamento e metriche significative
Per trovare rapidamente i blocchi, ho bisogno di Correlazione continua. Assegno ID di richiesta (ad esempio, traceparent) all'edge, al server web, all'app e al database e li scrivo nei log. Questo mi permette di vedere se una richiesta fallisce nel WAF, è in attesa nel server web, è bloccata nella coda di FPM o è bloccata nel database. Lavoro con Istogrammi invece dei valori medi puri e monitoro la latenza P95/P99, le connessioni aperte, la coda di accettazione, la lunghezza della coda FPM, le sessioni DB attive e i codici di errore del backend. Utilizzo anche controlli sintetici per separare chiaramente gli effetti del lato client da quelli del lato server.
Per le anomalie utilizzo un Discesa libera-La procedura: prima i log edge/WAF, poi il bilanciatore di carico, poi gli accessi/errori del server web, poi i log di app e FPM e infine i log di DB e di sistema. Questo percorso mi mostra esattamente dove si perde tempo e a quale limite si ferma la richiesta. Grazie a metriche mirate per livello, evito le sensazioni di pancia e riduco drasticamente i tempi per arrivare alla causa principale.
Manuale e lista di controllo per la messa a punto
In pratica, ho un libro di giochi compatto che adatto all'ambiente:
- Riproducibilità: Individuare lo scenario (percorso, metodo, dimensione, client), la data e l'ora del log e gli ID.
- Controllare strato per stratoBrowser/Estensioni, CORS/Preflight, WAF-Hits, LB-Stats, Webserver-Status, FPM-Queue, DB-Active/Locks.
- Rendere visibili le codeBacklog di accettazione/SYN, coda di ascolto FPM, backlog proxy, pool di connessioni DB.
- Sincronizzare i limitiWorker/thread, somaxconn, nofile, max_connections, limiti di flusso per H2/H3, limiti di body/header, timeout.
- Riduzione del tempo di occupazioneAccelerare le query, evitare i blocchi di sessione, ridurre l'I/O, comprimere le risposte e metterle in cache in modo sensato.
- Armonizzare le strategieDurata del Keep-Alive, parametrizzazione HTTP/2/3, prioritizzazione dei percorsi critici.
- Regolare la sicurezzaEsclusione mirata delle regole WAF anziché indebolimento globale; registrazione con ID di risposta.
- ScalaDefinire la concurrency per turno, eseguire test di carico, misurare le riserve, aumentare i limiti solo dopo l'ottimizzazione.
- RicaduteInterruttore automatico per i backend lenti, politica di ritentativi con jitter, „stale-if-error“ per gli asset critici.
Riassumendo brevemente
Le richieste bloccate con CPU e RAM libere sono solitamente causate da limiti, filtri e strategie di connessione, non da una mancanza di prestazioni. Innanzitutto verifico dove si ferma la richiesta: browser, WAF, server web, runtime o database. Quindi riduco al minimo i tempi di occupazione per slot, rimuovo le richieste non necessarie. Serrature e impostare timeout realistici. Mantengo alta la sicurezza, regolo le regole contro i falsi allarmi e raccolgo prove nei registri. Con questo approccio, le richieste HTTP rimangono accessibili in modo affidabile, anche quando il traffico aumenta e ogni secondo è importante.


