...

Hvorfor HTTP-anmodninger kan blokere, selv om der er nok ressourcer til rådighed

HTTP-anmodninger kan blokere, selv om CPU, RAM og båndbredde ser ud til at være åbne, fordi usynlige grænser, filtre og køer træder i kraft i hele kæden. Jeg forklarer, hvor Grænser hvordan de fungerer, og hvilke indstillinger jeg sætter, så forespørgsler kører problemfrit igen.

Centrale punkter

Før jeg går i detaljer, vil jeg opsummere de vigtigste årsager og nævne, hvad jeg ser på først. Disse punkter dækker de typiske flaskehalse, der fører til overbelastning på trods af frie ressourcer. Jeg har med vilje holdt listen kompakt, så du straks kan tjekke udgangspunktet. Det vigtigste er, at hvert lag har sine egne regler, som gælder uafhængigt af CPU og RAM. Hvis du kender disse regler, kan du hurtigt løse mange „uforklarlige“ ventetider.

  • Grænser for arbejdereFor få processer/tråde blokerer for nye forbindelser på trods af ledig CPU.
  • SikkerhedslagWAF/webfiltre blokerer mønstre, metoder eller klienter, ofte uden høj belastning.
  • SamtidighedPHP-FPM, database og proxyer begrænser antallet af samtidige sessioner.
  • Keep-Alive/TimeoutsLange forbindelser optager tid, og forespørgsler ender i kø.
  • Klient-filterBrowserudvidelser stopper anmodninger, før de når frem til serveren.

Disse nøglepunkter er ofte nok til at kontrollere adfærd på en målrettet måde. I det følgende vil jeg vise dig, hvordan jeg udleder specifikke foranstaltninger fra dette og Blokeringer rent.

Hvorfor HTTP-anmodninger blokerer trods ledige ressourcer

En anmodning passerer gennem flere lag: Klient, netværk, filter, webserver, runtime-miljø og database. Hvert lag har sin egen Grænser som træder i kraft uanset CPU, RAM eller båndbredde. Hvis worker-slots er optaget, eller regler er aktive, venter anmodningen i en kø eller bliver straks annulleret. Denne ventetid vises ofte slet ikke i klassiske ressourcediagrammer. Det er netop det, der fører til den misforståelse, at serveren er „tom“, selv om der ikke besvares anmodninger.

Sikkerhedslag: WAF, filtre og udbyderregler

Mange blokeringer opstår, før applikationen overhovedet kører. Firewalls til webapplikationer, IDS/IPS og filtre på udbydersiden genkender mønstre og gør dem langsommere eller blokerer dem [1][5][9]. Mistænkelige parametre, gamle protokoller eller kombinationer af metoder er nok til at forårsage en Lås at antænde. Fra operatørens synspunkt ser det ud som en serverfejl, men beslutningen træffes „upstream“. Jeg tjekker derfor WAF-logfilerne og noterer request-ID, IP, tid og statuskode. Med disse data kan reglen identificeres og justeres på en målrettet måde uden at gå på kompromis med sikkerheden.

Klientsiden: browserudvidelser og lokale blokeringer

Ikke alle anmodninger når frem til serveren. Adblockere, adgangskodeadministratorer og scriptblokkere stopper allerede URL'er i browseren; DevTools viser derefter „Anmodninger til serveren er blevet blokeret af en udvidelse“ [3][7]. Jeg tester i et privat vindue, deaktiverer udvidelser og kontrollerer, om Anmodning overhovedet blev sendt. Det hjælper også med at styre prioriteterne i frontend, for eksempel med en ren Prioritering af anmodninger for kritiske aktiver. Det forhindrer ikke-kritiske tredjepartsopkald i at forsinke vigtige ruter.

Forståelse af metode og routing: 405, 403, 429

En 405 „Method Not Allowed“ viser tydeligt, at serveren anerkender ressourcen, men ikke tillader den anvendte metode [5]. På samme måde indikerer 403 filtre eller rettigheder og 429 aktiv hastighedsbegrænsning. I logfiler kan jeg hurtigt se, om en global regel tillader metoder som f.eks. PUT eller DELETE, eller om et endpoint aldrig er blevet implementeret. Derefter justerer jeg routingen, controlleren eller WAF-reglen. På denne måde opløses den formodede „blokering“ i en ren korrektion af metoder og stier.

Webserver-arkitektur og arbejdsbegrænsninger

Apache, NGINX, LiteSpeed og OpenLiteSpeed håndterer forbindelser forskelligt [4]. De afgørende faktorer er antallet af arbejdsprocesser, tråde og hvordan keep-alive-sockets optager slots. Hvis alle workers er optaget af lange forbindelser, flyttes nye forespørgsler til en , selvom CPU'en og RAM'en ser ud til at være fri. Jeg analyserer derfor forbindelsestilstande og justerer workers, backlogs og keep-alive-tider. Baggrundsviden om køer hjælper, for eksempel med emnet Serverkø og ventetid.

lag Relevant grænse Typisk symptom Diagnostisk note
Webserver Antal arbejdere/tråde Køer, 503 under belastning Statusmoduler, tjekker forbindelsesstatusser
PHP-FPM/FastCGI max_børn / pm Hængende forespørgsler, høj time-to-first-byte FPM-logfiler, langsom log, antal processer
Database max_forbindelser Fejl „For mange forbindelser“ VIS PROCESSLISTE, forbindelsestoppe
WAF/Filter Underskrifter, metoder 403/405, ødelagte formularindlæg WAF-logfiler, regel-hit-id'er
Load Balancer Begrænsning pr. backend-conn Inkonsekvente svartider LB-statistik, Backend-sundhed

Samtidighed i PHP-FPM, database og proxyer

Samtidig behandling kommer ofte først i runtime-miljøet. Hvis alle PHP FPM-medarbejdere har travlt, er der ikke plads til nye scripts; anmodningerne venter, selv om CPU virker næsten ikke. Situationen er den samme for databaser med max_connections eller for proxyer med forbindelsesgrænser pr. backend. Jeg optimerer først varigheden af de enkelte anmodninger, før jeg øger grænserne. På den måde forkorter jeg dokumenttiden pr. slot og reducerer sandsynligheden for, at køerne vokser.

Langsomme backends og låsning af PHP-sessioner

Lange databaseforespørgsler, eksterne API'er eller fil-I/O binder medarbejderne betydeligt længere. Sessionslåsning kan også gøre hele kæder langsommere, f.eks. WordPress-logins eller indkøbsvogne. Jeg tjekker, om parallelle forespørgsler til det samme sessions-ID kører efter hinanden i stedet for samtidig. Hvis det er tilfældet, bruger jeg målrettet oplåsning, reducerer kritiske skriveadgange og følger de velafprøvede instruktioner på Låsning af PHP-sessioner. Det giver mig mulighed for at frigøre slots hurtigere og reducere Ventetider Bemærkelsesværdigt.

Timeouts, keep-alive og forbindelsesstrategier

Keep-alive-tider, der er for lange, binder ressourcer, mens de, der er for korte, genererer handshakes og ventetid. Jeg vælger værdier, der matcher trafikprofilen, og sætter grænser for header-, body- og backend-timeouts. Det er vigtigt at indstille timeouts ikke kun på Webserver men standardiseret i hele kæden: proxy, app, database. Derudover forhindrer jeg inaktiv blokering gennem finere HTTP/2/HTTP/3-indstillinger og prioritering. Dette holder slots tilgængelige, uden at klienter konstant skal oprette forbindelse igen.

Hosting-modeller: Delt, VPS, Dedikeret

Delt hosting indstiller tidlige filtre og hårde kvoter, så platformen forbliver fair [1]. På VPS isolerer udbyderne CPU og RAM, men opretholder grænser for I/O, netværk eller sikkerhed; forskelle i ydeevne og overvågning er tydelige [10]. På dedikerede servere har jeg det fulde ansvar for webserver-, database- og WAF-konfigurationen. Sammenligninger viser, at moderne stakke med HTTP/3, NVMe og DDoS-beskyttelse giver klare fordele [2][6][11][8]. De, der har brug for høj parallelitet, nyder godt af klart dokumenterede Grænser og støtte, som hjælper med reglenheder.

Systematisk analyse: trin for trin

Jeg starter ved kilden: Sender DevTools virkelig anmodningen, eller er det en udvidelse [3][7], der blokerer den? Derefter ser jeg på statuskoder: 403/405/429/503 giver stærke indikationer på filtre, metoder eller kapacitet [5]. Samtidig tjekker jeg logfiler fra webserveren, appen og WAF for at finde mønstre og tilbagevendende signaturer [1][9]. Derefter tjekker jeg antallet af arbejdere, FPM-parametre, keep-alive og databaseforbindelser og øger grænserne på testbasis med målepunkter før og efter. Til sidst simulerer jeg belastningen, observerer flaskehalse i realtid og kontrollerer, at Køer krympe.

Bedste praksis mod blokader

Jeg formulerer mål for samtidighed pr. lag og sætter grænser, så belastningstoppe dæmpes. Webserveren skal matche trafikmønsteret; benchmarks hjælper med udvælgelsen og konfigurationen [4]. Jeg optimerer først backends logisk: hurtigere forespørgsler, kortere transaktioner, færre serielle sektioner. Jeg holder sikkerhedsreglerne strenge nok mod angreb, men med undtagelser for legitime angreb. Prøve. Overvågningen slutter ikke med CPU/RAM: Jeg ser på forbindelser, køer, svartider og fejlkoder, så flaskehalse forbliver synlige [6][11].

Øvelsesnoter: hosting med blokering af anmodninger

I delte miljøer ender blokader ofte før det faktiske webhotel; support har derefter brug for specifikke forespørgselsdata for at justere reglerne [1]. På VPS skalerer jeg gradvist: flere arbejdere, mere passende keep-alive-værdier og tættere overvågning af databasen [10]. På min egen hardware beslutter jeg mig for belastningsbalancering, WAF-regler og grænser pr. backend. Projekter med meget parallel adgang nyder godt af en ren HTTP/2/HTTP/3-konfiguration og klare reserver til Tips. Hvis du forventer vækst, skal du planlægge skiftet til kraftigere tariffer tidligt og spare en masse indstillingsarbejde senere [2][6][10][11].

Netværks- og kernelgrænser: backlog, porte og deskriptorer

Ud over webserveren og appen begrænser kernen, hvor mange forbindelser der kan ankomme, etableres og håndteres på samme tid. Jeg tjekker først Liste over efterslæbSelv om webserveren har mange arbejdere, kan acceptkøen være kort. Samspillet mellem applikationen (listen backlog), kernen (somaxconn) og SYN backlog (tcp_max_syn_backlog) afgør, om forbindelserne forbliver i køen eller bliver kasseret. Symptomerne er stigende forbindelsestider og retransmissioner - med lav CPU-udnyttelse. Jeg sammenligner værdierne og måler den faktiske udnyttelse af køerne for at undgå udfald.

En anden klassiker er conntrack-bord til NAT/firewall-opsætninger. Hvis den er fuld, forsvinder forbindelserne „sporløst“; programmet ser aldrig en anmodning. Jeg genkender det på beskeder i systemloggen og pludselige timeouts under spidsbelastninger. Modforanstaltningerne er: passende tabelstørrelse, realistiske idle timeouts for protokoller, færre unødvendige NAT-stier og effektive keep-alives, der genbruger forbindelser på en fornuftig måde.

Jeg tjekker også antallet af åbne Filbeskrivelser (ulimit -n). Hvis mange samtidige sockets og filer rammer restriktive grænser, fejler Accept („for mange åbne filer“), og nye anmodninger hober sig op foran den. Løsningen er normalt triviel: Indstil nofile-grænserne for webserveren, proxyen og databasen til et sundt niveau - vedvarende, ikke kun interaktivt.

I stærkt parallelle opsætninger observerer jeg Kortvarigt portområde og TIME_WAIT-tilstande. Især bag NAT-gateways bliver de tilgængelige kildeporte opbrugt, når korte forbindelser etableres i massevis. Derfor benytter jeg mig af genbrug af forbindelser (keep-alive, HTTP/2/3), reducerer unødvendige kortvarige forbindelser og indstiller TIME_WAIT-håndteringen omhyggeligt uden at risikere stabiliteten. Resultatet: mindre portudmattelse og mere stabile forbindelsestider under belastning.

På netværkskortet tjekker jeg kø-længder, offloading-indstillinger og IRQ-fordeling. Ujævnt fordelte afbrydelser eller overbelastede køer genererer latenstidstoppe, som ikke kan ses i programlogfiler. Med afbalanceret IRQ-balancering og fornuftige Qdisc-indstillinger (nøgleord Bufferbloat) Jeg reducerer ventetiden uden at begrænse båndbredden.

HTTP/2 og HTTP/3: Brug multiplexing korrekt

Multiplexing løser mange problemer, men medfører også nye begrænsninger: Maksimalt antal strømme, flow control window og idle timeouts gælder pr. forbindelse. Hvis værdien for samtidige streams er for lav, „hænger“ nye forespørgsler, selv om TCP- eller QUIC-forbindelsen er etableret. Jeg tjekker derfor, hvor mange kritiske ressourcer, der skal indlæses parallelt, og justerer omhyggeligt stream-grænserne. Samtidig er jeg opmærksom på rimelige Kontrol af flow-vindue, så store svar ikke bliver neddroslet.

HTTP/2-multiplexer over TCP kan lide af head-of-line-blokering i tilfælde af pakketab; HTTP/3 på QUIC undgår dette, men kræver rene TLS/ALPN-indstillinger og stabile stihåndteringsregler. Jeg tester begge stier og vælger de protokoller, der matcher trafikprofilen. Vigtigt: Stol ikke blindt på prioritering - browsere og servere fortolker det forskelligt. Jeg fokuserer på kritiske ruter og tjekker, om prioriteringerne rent faktisk fungerer, og om pladserne ikke optages af langvarige sekundære strømme.

CORS, preflights og header/body-grænser

Ikke alle 4xx-fejl kommer fra serveren. CORS-overtrædelser opstår i browseren og vises i konsollen, ikke i adgangsloggen. Jeg kontrollerer, om preflight-anmodninger (OPTIONS) besvares korrekt, og om WAF/proxies tillader denne metode. Hvis overskrifter som Access-Control-Allow-Methods/-Headers mangler, „blokerer“ browseren svaret - uden nogen serverbelastning.

Endnu en flaskehals: Header- og cookie-størrelser. Overgroede cookies, mange Vary-headere eller store referer-linjer fører til 431-fejl eller lydløse udfald på grund af bufferbegrænsninger. Jeg begrænser cookie-ballast, konsoliderer headers og indstiller bufferstørrelser konsekvent langs kæden. Ved uploads er jeg opmærksom på body-grænser, 100-continue-håndtering og konsekvent Chunked-kodning-Understøttelse af alle proxyer. Hvis body- og uploadgrænserne ikke stemmer overens, venter klienter på en frigivelse, der aldrig kommer - anmodninger ser ud til at „hænge“.

DNS og TLS: Håndtryk som skjult latenstid

DNS-opløsning og TLS-forhandling er ofte blinde pletter. Flere CNAME-kæder, langsomme resolvere eller IPv6/IPv4-mismatch forlænger starttiden uden at bruge CPU. Jeg reducerer unødvendige DNS-spring, indstiller fornuftige TTL'er og sikrer hurtige resolver-stier. På TLS-siden tjekker jeg certifikatkæder, aktiverede cipher suites, OCSP-hæftning og genoptagelse af sessioner. Et rent ALPN-handshake forhindrer nedgraderinger til HTTP/1.1, som lægger et større pres på keep-alive-slots. Resultat: kortere time-to-first-byte og mere stabil parallelitet, især på mobilnetværk.

CDN/Edge: Caching, hastighedsgrænser og IP-omdømme

Mellem klient og oprindelse beslutter CDN'er, reverse proxyer og DDoS-beskyttelsessystemer sig for Kulvert og drosler ned. Jeg tjekker, om kritiske ruter er cached korrekt (stale-while-revalidate, stale-if-error), og om negative caches holder på fejl længere end nødvendigt. Hastighedsgrænser, bot-styring og IP-omdømme kan dæmpe legitim trafik, især med delte netværk eller tung API-adgang. Jeg segmenterer trafik (f.eks. API vs. aktiver), definerer klare cachenøgler og deaktiverer regler selektivt for betroede klienter. Det aflaster Origin og forhindrer CDN-køer i at vokse, mens serveren ser ud til at være „underudnyttet“.

Containere og orkestrering: cgroups, Ingress og conntrack

I beholdere gælder cgroup-grænser for CPU, RAM, pids og filer. En for stram CPU-kvote fører til throttling: Processer venter på CPU-tid, selv om værten er ledig. Jeg tjekker kvoter og sørger for, at ingress/proxy-pods har nok filbeskrivelser og buffere. I Kubernetes tjekker jeg ingress-timeouts, readiness/liveness-probes og serviceimplementeringer (IPVS), fordi defekte probes eller timeouts skaber zigzag-latency og unødvendige genstarter.

En ofte overset flaskehals er NAT/conntrack-kapacitet pr. node. Mange kortvarige forbindelser (f.eks. udgang til eksterne API'er) fylder conntrack-tabellen, og derefter „forsvinder“ anmodningerne i netværket. Jeg skalerer tabellen, indstiller realistiske timeouts og bundter eksterne opkald, så der oprettes færre nye forbindelser. Jeg planlægger PodDisruptionBudgets, rullende opdateringer og HPA-skalering på en sådan måde, at der ikke trækkes kapacitet fra planlæggeren i spidsbelastningsperioder - ellers dannes der køer, selv om appen teoretisk set ville have nok arbejdere.

Observerbarhed: korrelation, sporing og meningsfulde målinger

For at finde blokeringer hurtigt har jeg brug for Kontinuerlig korrelation. Jeg tildeler request-id'er (f.eks. traceparent) til edge, webserver, app og database og skriver dem i logfilerne. Det giver mig mulighed for at se, om en anmodning fejler i WAF'en, venter på webserveren, sidder fast i FPM-køen eller er blokeret i databasen. Jeg arbejder med Histogrammer i stedet for rene gennemsnitsværdier og overvåger P95/P99-latency, åbne forbindelser, acceptkø, FPM-kølængde, aktive DB-sessioner og backend-fejlkoder. Jeg bruger også syntetiske kontroller til klart at adskille effekter på klientsiden fra effekter på serversiden.

Til anomalier bruger jeg en DrilldownProceduren: først edge/WAF-logfiler, så load balancer, så webserveradgang/fejl, så app- og FPM-logfiler og til sidst DB- og systemlogfiler. Denne sti viser mig præcis, hvor tiden går tabt, og ved hvilken grænse anmodningen stopper. Med målrettede målinger pr. lag undgår jeg mavefornemmelser og reducerer drastisk tiden til den grundlæggende årsag.

Tuning-playbook og tjekliste

I praksis har jeg en kompakt drejebog, som jeg tilpasser til omgivelserne:

  • Reproducerbarhed: Fastlæg scenarie (rute, metode, størrelse, klient), logtidsstempel og ID'er.
  • Tjek lag for lagBrowser/udvidelser, CORS/Preflight, WAF-Hits, LB-Stats, Webserver-Status, FPM-Queue, DB-Active/Locks.
  • Gør køer synligeAccept/SYN-backlog, FPM-lyttekø, proxy-backlog, DB-forbindelsespulje.
  • Synkroniser grænserWorker/threads, somaxconn, nofile, max_connections, stream-grænser for H2/H3, body/header-grænser, timeouts.
  • Reducer belægningstidenFremskynd forespørgsler, undgå sessionslåse, reducer I/O, komprimér svar og sæt dem i cache på en fornuftig måde.
  • Harmoniser strategierKeep-Alive-varighed, HTTP/2/3-parametrisering, prioritering af kritiske ruter.
  • Juster sikkerheden: Målrettet udelukkelse af WAF-regler i stedet for global svækkelse; logning med hit-id'er.
  • SkaleringDefiner samtidighed pr. skift, kør belastningstest, mål reserver, øg kun grænserne efter optimering.
  • TilbagefaldCircuit breaker til langsomme backends, retry policy med jitter, „stale-if-error“ til kritiske aktiver.

Kort opsummeret

Blokerede forespørgsler med ledig CPU og RAM skyldes som regel grænser, filtre og forbindelsesstrategier - ikke manglende ydeevne. Jeg tjekker først, hvor forespørgslen stopper: browser, WAF, webserver, runtime eller database. Derefter minimerer jeg belægningstiden pr. slot, fjerner unødvendige Låse og indstiller realistiske timeouts. Jeg holder sikkerheden høj, justerer regler mod falske alarmer og indsamler beviser i logfiler. Med denne tilgang forbliver HTTP-anmodninger pålideligt tilgængelige - selv når trafikken stiger, og hvert sekund tæller.

Aktuelle artikler