PHP-anmodningskøer begrænser, hvor mange anmodninger din server behandler på samme tid, og bestemmer derfor svartid, fejlrater og brugeroplevelse. Jeg vil vise dig, hvordan du Grænser for behandling og eliminere flaskehalse og opnå ensartet levering gennem harmoniserede parametre.
Centrale punkter
For at du kan komme i gang med det samme, vil jeg opsummere de vigtigste justeringsskruer til PHP-FPM sammen.
- pm.max_børn: Beregn den øvre grænse for samtidige PHP-processer, så de passer til RAM.
- listen.backlog: Maksimer kortvarig buffering af forbindelsesforsøg under spidsbelastninger.
- pm.max_anmodningerGenbrug processer regelmæssigt for at undgå hukommelseslækager og oppustethed.
- Timeouts: sæt request_terminate_timeout, max_execution_time og webserver timeouts konsekvent.
- Metrikkermax børn nået, tjek lyttekøen og slowlogs løbende.
Jeg fokuserer på klare nøgletal og målbare effekter, så enhver justering af Grænser forbliver sporbar. For hver ændring overvåger jeg logfiler og svartider, før jeg planlægger det næste skridt og gradvist øger eller mindsker værdierne. På den måde forhindrer jeg bivirkninger som f.eks. memory swapping, som kan Kø dramatisk længere. Med denne tilgang bringer jeg spidsbelastninger under kontrol og holder svartiderne stabile. Målet er at opnå en afbalanceret kapacitetsudnyttelse, der Ressourcer effektivt uden at overbelaste værten.
Sådan fungerer PHP Request Queueing i PHP-FPM
Hver indgående HTTP-anmodning kræver sin egen Arbejder, og en worker betjener kun én anmodning ad gangen. Hvis alle processer er optaget, ender yderligere opkald i Kø og vente på, at en proces bliver ledig. Hvis denne kø vokser, stiger svartiderne, og fejl som 502/504 forekommer hyppigere. Jeg er derfor opmærksom på et fornuftigt forhold mellem antallet af processer og den tilgængelige hukommelse i stedet for blindt at fokusere på maksimal parallelitet. På den måde opnår jeg en konstant gennemstrømningshastighed uden at RAM eller CPU'en bryder væk.
Vælg processtyringstilstande rent
Ud over grænseværdierne er pm-tilstand reaktionsevne og ressourceforbrug:
- pm = dynamiskJeg definerer start_servers, min_spare_servers og max_spare_servers. Denne tilstand er min standard for variable belastninger, fordi den reagerer hurtigt på stigninger og holder varme processer klar.
- pm = ondemandProcesser oprettes kun, når det er nødvendigt, og afsluttes efter process_idle_timeout. Det sparer RAM til sjældne adgange (admin, staging, cron endpoints), men kan føre til tab af RAM i tilfælde af pludselige spidsbelastninger. Koldstart og højere latenstid. Jeg bruger det derfor selektivt og med en generøs backlog.
- pm = statisk: Et fast antal processer. Ideelt, hvis jeg har en hård øvre grænse og særligt forudsigelige ventetider (f.eks. L7-proxy foran nogle få, men kritiske slutpunkter). RAM-kravet kan klart beregnes, men ubrugte processer binder hukommelsen.
Jeg beslutter, hvilken tilstand der passer til profilen for hver pulje. Jeg bruger normalt dynamisk til frontends med varierende belastning, ondemand til utility-pools og statisk til dedikerede, latency-kritiske tjenester.
Bestem pm.max_children korrekt
Det vigtigste håndtag er pm.max_børn, fordi denne værdi definerer, hvor mange anmodninger der kan køre samtidig. Jeg beregner startstørrelsen ved hjælp af tommelfingerreglen: (frit tilgængelig RAM - 2 GB reserve) divideret med den gennemsnitlige hukommelse per PHP-proces. Som en grov antagelse bruger jeg 40-80 MB pr. proces og starter med 200-300 processer på en 32 GB host. Under live-belastning øger eller mindsker jeg gradvist og kontrollerer, om ventetiden på Kø falder, og fejlraten bliver mindre. Hvis du vil dykke dybere ned, kan du finde baggrundsinformation om start- og grænseværdier på Optimer pm.max_children.
Koordiner start-, reserve- og backlog-værdier
Jeg sætter pm.start_servers til omkring 15-30 procent af pm.max_children, så der er nok processer til rådighed i starten, og der ikke er nogen koldstart. Med pm.min_spare_servers og pm.max_spare_servers definerer jeg et rimeligt vindue for frie processer, så nye forespørgsler ikke venter, og der samtidig ikke er unødvendig tomgangstid, der binder hukommelsen. Listen.backlog er særlig vigtig: Denne kernebuffer rummer kortvarigt ekstra forbindelsesforsøg, når alle arbejdere har travlt. Ved spidsbelastninger sætter jeg høje værdier (f.eks. 65535), så kø ikke stopper før FPM-puljen. Mere dybdegående baggrundsinformation om samspillet mellem webserveren, upstream og buffere kan findes i oversigten over Kø til webserver.
Begræns anmodningernes køretid, og genbrug processerne
Jeg forhindrer snigende hukommelsesstigninger med pm.max_anmodninger, som genstarter alle processer efter X anmodninger. Uhøjtidelige applikationer kører ofte godt med 500-800, men hvis der er mistanke om hukommelseslækager, reducerer jeg til 100-200 og observerer effekten. Derudover indkapsler request_terminate_timeout outliers ved at afslutte ekstremt langvarige forespørgsler efter en fast tid. Konsistens er vigtig: Jeg holder PHP's max_execution_time og webserverens timeouts i samme korridor, så det ene lag ikke afsluttes tidligere end det andet. Dette samspil holder Arbejder fri og beskytter poolen mod overbelastning.
Gør køer synlige: Logfiler og metrikker
Jeg læser regelmæssigt FPM-logfilerne og er opmærksom på max antal børn nået, fordi denne post indikerer, at den øvre grænse for processerne er nået. Samtidig overvåger jeg lyttekøen, som afslører et stigende efterslæb i inputbufferen. I kombination med request_slowlog_timeout får jeg stack traces for langsomme punkter i koden og kan isolere database- eller API-bremser. Jeg korrelerer upstream_response_time fra webserverloggene med request_time og statuskoder for at indsnævre kilden til lange svartider. Dette giver mig mulighed for at genkende, om flaskehalsen i PHP-FPM, den Database eller upstream-netværket.
Profiler for arbejdsbelastning: CPU-bundet vs. IO-bundet
For CPU-tunge processer skalerer jeg Parallelisme Jeg er forsigtig og orienterer mig nøje efter vCPU-nummeret, fordi yderligere processer næppe giver noget throughput. Hvis det hovedsageligt er en IO-belastning med databaseadgang eller eksterne API'er, kan jeg tillade flere processer, så længe RAM-budgettet er tilstrækkeligt. E-handelskasser har gavn af længere timeouts (f.eks. 300 s) for at kunne gennemføre betalingsmetoder uden annulleringer. Jeg opfanger lynsalg ved at sætte listen.backlog højt og øge reservevinduet. Oplysninger om balancen mellem antallet af processer og værtens ydeevne er samlet i vejledningen til PHP-Workers som flaskehals.
Eksempel på beregninger og dimensionering
Jeg beregner først hukommelsen pr. proces og udleder derefter en fornuftig Øvre grænse af. Derefter tester jeg under reel belastning og observerer, om køen bliver mindre, og om gennemstrømningen stiger. Konservative startværdier reducerer risikoen for swapping og holder svartiden jævn. Jeg forfiner derefter i små trin for at være sikker på at bemærke eventuelle bivirkninger. Følgende tabel giver vejledning om startværdier og effekter på Kø.
| Parametre | Effekt | Startværdi (eksempel) | Hint |
|---|---|---|---|
| pm.max_børn | Maks. samtidig Processer | 200-300 (med 32 GB) | Sammenlign med RAM-budget og processtørrelse |
| pm.start_servers | Oprindeligt antal arbejdere | 15-30 % fra max_børn | Undgå koldstart, men hold tomgang på et minimum |
| pm.min_spare_servers | Gratis Arbejder Minimum | z. B. 20 | Direkte inddragelse af nye anmodninger |
| pm.max_spare_servere | Maksimum for frie arbejdere | z. B. 40 | Begræns RAM-forbruget af inaktive processer |
| listen.backlog | Kernel-buffer til forbindelsesforsøg | 65535 | Dæmp spidsbelastninger og reducer afbrydelser i forbindelsen |
| pm.max_anmodninger | genanvendelse Interval | 500-800, med lækager 100-200 | Minimér mængden af hukommelse og hængepartier |
| request_terminate_timeout | Hård anmodningsgrænse | 300-600 s | I overensstemmelse med timeouts for PHP og webservere |
Praktiske skabeloner til PHP FPM-pools
For en butik med mange læseadgange sætter jeg moderat Tal for processen og øg reservevinduet, så anmodninger ikke sættes i kø. For indholdssider med caching er det ofte tilstrækkeligt med betydeligt færre arbejdere, så længe NGINX eller Apache leverer statisk indhold effektivt. Jeg adskiller multi-pool-opsætninger i henhold til applikationsdele, der har forskellige hukommelsesprofiler, så ingen tung pool fortrænger de andre. Jeg definerer separate puljer med deres egne timeout-regler for cron- eller køarbejdere. Sådan holder jeg den interaktive Trafik gratis og bremser ikke nogen brugerhandlinger.
Webserver-timeouts, upstream og sockets
Jeg betragter FastCGI og proxy-timeouts fra Nginx eller Apache i samme vindue som FPM's timeouts, så intet lag afsluttes for tidligt. Jeg foretrækker Unix-sockets frem for TCP, hvis begge tjenester kører på den samme vært, fordi ventetiden forbliver minimal. Til distribuerede opsætninger bruger jeg TCP med stabile keepalive-værdier og en tilstrækkelig stor forbindelsespulje. Ved høj parallelitet synkroniserer nginx worker_connections og FPM's backlog-værdier. Det sikrer, at omdirigeringer forbliver hurtige, og jeg undgår inaktiv tid på grund af for tætte forbindelser. Opstrøms-begrænsninger.
Caching, OPCache og database som løftestang
Jeg løser mange serverproblemer ved at reducere dyre operationer og minimere Svartid lavere. Jeg slår OPCache til, øger hukommelsesgrænsen for cachen fornuftigt og sikrer en høj cache-hitrate. For at opnå tilbagevendende resultater bruger jeg applikationscaching, så PHP-processer afsluttes hurtigere. På databasesiden optimerer jeg langsomme forespørgsler og aktiverer forespørgselscacher, der passer til det anvendte system. Hvert millisekund, der spares, reducerer belastningen på Kø og øger gennemstrømningen pr. medarbejder.
Sikre nødmekanismer og genstart
Jeg aktiverer emergency_restart_threshold og emergency_restart_interval, så FPM-masteren genstarter, hvis for mange børn går ned hurtigt efter hinanden. Denne kontrollerede genstart forhindrer kædereaktioner og holder tjenesten tilgængelig. Samtidig sætter jeg klare grænser for hukommelse og antallet af processer for at forhindre eskalering. Sundhedstjek på upstream-siden fjerner automatisk defekte backends fra puljen og reducerer fejlraten. Dette holder Tilgængelighed mens jeg undersøger den egentlige årsag.
Finjuster operativsystemets og systemd's grænser
Så det listen.backlog faktisk træder i kraft, justerer jeg kernegrænserne. OS-værdien net.core.somaxconn skal være mindst lige så høj som den indstillede backlog, ellers afbryder systemet køen. Jeg tjekker også antallet af tilladte filbeskrivelser: I FPM-poolen kan jeg indstille rlimit_files, på serviceniveau sikrer jeg LimitNOFILE (systemd) og på kerneniveau fs.file-max. Webserveren har brug for lignende reserver, så den ikke når sine grænser tidligere.
For mere stabile ventetider reducerer jeg vm.swappiness, så kernen ikke fortrænger aktivt brugte hukommelsessider for tidligt. I latency-kritiske opsætninger deaktiverer jeg Gennemsigtige store sider, for at undgå lange sidefejl. Hvis FPM kører via TCP, synkroniserer jeg også net.ipv4.tcp_max_syn_backlog og reuse/keepalive-parametre. Sådanne OS-detaljer virker uanselige, men de afgør, om køer glat udløber, eller om forbindelser allerede er afvist før FPM.
Mål modstandsdygtigt hukommelse pr. proces
I stedet for at lave generaliserede estimater måler jeg Reelt forbrug pr. medarbejder under reel belastning. Jeg bruger værktøjer som ps, smem eller pmap, filtrerer efter php-fpm-børn og tager gennemsnittet af RSS-værdierne, mens forespørgslerne kører. Det er vigtigt at tage højde for den delte OPCache-brug: delt hukommelse tælles ikke flere gange. Jeg udleder pm.max_children fra den gennemsnitlige værdi og planlægger også en reserve, så maskinen ikke løber ind i en flaskehals, selv under spidsbelastninger. Byttehandel hælder.
Jeg gentager denne måling efter ændringer i funktioner eller udgivelser. Nye funktioner, flere afhængigheder eller ændringer i frameworks kan øge fodaftrykket pr. proces betydeligt. Dette holder antallet af processer realistisk og køen kort.
PHP FPM-status, ping og live-målinger
For at få en hurtig vurdering af situationen aktiverer jeg pm.status_path og en Ping-slutpunkt (ping.path/ping.response). Over dette kan jeg se nøgletal som accepteret conn, listen queue len, idle/busy processer, max children reached og deres progression. Jeg læser disse værdier med jævne mellemrum og sætter tærskelværdier: Hvis lyttekøen stiger permanent, øger jeg enten antallet af processer eller fjerner årsagen til de langsomme anmodninger. Hvis maks. antal nåede børn stiger, mens inaktiviteten forbliver lav, er puljen for lille eller blokeret af lange løbere.
Jeg adskiller også pools med forskellige profiler, så spidsbelastninger på ét område (f.eks. API-import) ikke tvinger den interaktive trafik i knæ. I diagnostiske tilfælde øger jeg midlertidigt log_level og lader slowloggen optage flere prøver, men reducerer den derefter igen for at holde I/O-belastningen lav.
Uploads, buffering og store anmodninger
Store uploads kan binde medarbejderne unødigt op, hvis PHP først skal læse hele anmodningen. Jeg sørger for, at webserveren Buffere (f.eks. fastcgi_request_buffering til NGINX), så FPM først starter, når kroppen er færdig. Det betyder, at ingen arbejder blokerer under uploaden. Jeg bruger client_max_body_size, post_max_size og max_input_time til at kontrollere, hvor store og hvor lange forespørgsler der kan være, uden at det går ud over endpoints. Hvis der er filer imellem, tildeler jeg tilstrækkelig hurtig midlertidig hukommelse (SSD) for at undgå bufferstop.
For slutpunkter med meget store mængder (f.eks. eksport/import) definerer jeg dedikerede pools med deres egne timeouts og mindre parallelitet. Det efterlader standardarbejderne frie, og Kø af de vigtige brugerhandlinger.
Databaseforbindelser og poolgrænser
Selv den bedste FPM-indstilling er ubrugelig, hvis Database tidligere begrænset. Jeg tilpasser det maksimale antal samtidige PHP-processer til den faktiske tilgængelige DB-kapacitet. For vedvarende forbindelser eller forbindelsespuljer sørger jeg for, at summen af alle puljer er under max_connections forbliver. Hvis der er mange korte forespørgsler, hjælper det at begrænse PHP-paralleliteten moderat, så DB'en ikke går i stå mellem tusindvis af sessioner.
Langsomme transaktioner skaber hurtigt et efterslæb i FPM-køen. Jeg analyserer derfor ventetider på låse, brug af indekser og forespørgselsplaner. Enhver reduktion i DB-køretiden reducerer straks PHPDokumentets varighed og reducerer køernes længde.
Udgivelser og udrulninger uden spidsbelastning
Når jeg udruller nye versioner, undgår jeg kolde cacher og processtorme. Jeg bruger Genindlæsning i stedet for hårde genstarter, så eksisterende worker-anmodninger afsluttes rent (bemærk process_control_timeout). Jeg varmer OPCache op på et tidligt tidspunkt ved at køre kritiske stier én gang, før jeg skifter, eller ved at arbejde med preloading. Det forhindrer mange arbejdere i at parse klassefiler på samme tid, og Svartid stiger med stormskridt.
Med blå/grønne eller canary-strategier øger jeg gradvist belastningen og overvåger statussiderne. Først når køen, fejlraten og ventetiden forbliver stabil, øger jeg andelen af trafik. Denne kontrollerede tilgang beskytter mod spidsbelastninger under implementeringen.
Container- og VM-specialiteter
I containere er den opfattede Samlet opbevaringsvolumen ofte lavere end værtens rapporter. Jeg tilpasser pm.max_children strengt til cgroup-grænsen og planlægger en reserve mod OOM-killeren. Hukommelsesgrænserne i PHP (memory_limit) og fodaftrykket pr. proces skal stemme overens, ellers er en enkelt afvigelse nok til at afslutte containeren.
Hvis der ikke er noget swap i containeren, er der større sandsynlighed for hårde aflysninger. Derfor holder jeg processerne konservative, aktiverer genbrug og overvåger RSS-toppene i produktionsbelastningen. Her er flere slanke pools ofte mere robuste end én stor, monolitisk pool.
Kontrollerbar nedbrydning og modtryk
Hvis den Kø Jeg er afhængig af kontrolleret nedbrydning: Jeg leverer bevidst 503 med retry after til ikke-kritiske endpoints i tilfælde af overbelastning, reducerer dyre funktioner (f.eks. live-søgninger) og begrænser parallel adgang til hotspots. Det holder systemet responsivt, mens jeg afhjælper årsagen, i stedet for at alle brugere løber ind i timeouts.
Kort opsummeret
Jeg bringer PHP Request Queueing under kontrol ved smart at tilpasse antallet af samtidige processer til RAM-budgettet og typen af belastning. Høje backlog-værdier buffer toppe, timeouts på alle niveauer passer fint sammen, og genbrug fjerner snigende hukommelsesproblemer. Logfiler og målinger viser mig, om køen vokser, hvor forespørgsler sidder fast, og hvornår jeg skal stramme op. Med omhyggelige justeringer og målrettet caching reducerer jeg behandlingstiden pr. anmodning og øger gennemstrømningen. På denne måde leverer serverne konsekvent og undgår dyre Timeouts i hverdagen.


