PHP request queueing begränsar hur många förfrågningar din server behandlar samtidigt och bestämmer därför svarstid, felfrekvenser och användarupplevelse. Jag kommer att visa dig hur du Bearbetningsgränser och eliminera flaskhalsar samt uppnå konsekventa leveranser genom harmoniserade parametrar.
Centrala punkter
För att du ska kunna komma igång direkt sammanfattar jag här de viktigaste justerskruvarna för PHP-FPM tillsammans.
- pm.max_barn: Beräkna den övre gränsen för samtidiga PHP-processer för att matcha RAM-minnet.
- listen.backlog: Maximera kortsiktig buffring av anslutningsförsök under belastningstoppar.
- pm.max_förfrågningarÅtervinn processer regelbundet för att undvika minnesläckage och uppblåsning.
- Tidsfrister: ställa in request_terminate_timeout, max_execution_time och webbserverns timeouts på ett konsekvent sätt.
- Mätetalmax barn uppnåtts, kontrollera lyssningskön och slowlogs kontinuerligt.
Jag fokuserar på tydliga nyckeltal och mätbara effekter så att varje justering av Gränser förblir spårbar. För varje förändring övervakar jag loggar och svarstider innan jag planerar nästa steg och gradvis ökar eller minskar värdena. På så sätt förhindrar jag bieffekter som minnesbyten, vilket kan Kö dramatiskt längre. Med den här metoden får jag belastningstoppar under kontroll och håller svarstiderna stabila. Målet är att uppnå ett balanserat kapacitetsutnyttjande som Resurser effektivt utan att överbelasta värden.
Hur PHP Request Queueing fungerar i PHP-FPM
Varje inkommande HTTP-begäran kräver sin egen Arbetare, och en arbetsprocess betjänar bara en begäran i taget. Om alla processer är upptagna hamnar ytterligare anrop i Kö och vänta tills en process blir ledig. Om denna kö växer ökar svarstiderna och fel som 502/504 inträffar oftare. Jag är därför uppmärksam på ett vettigt förhållande mellan antalet processer och tillgängligt minne istället för att blint fokusera på maximal parallellism. På så sätt uppnår jag en konstant genomströmningshastighet utan att RAM eller CPU bryter sig loss.
Välj processhanteringslägen på ett rent sätt
Förutom gränsvärdena kan pm-läge responstid och resursförbrukning:
- pm = dynamiskJag definierar start_servers, min_spare_servers och max_spare_servers. Det här läget är min standard för varierande belastningar eftersom det reagerar snabbt på ökningar och håller varma processer redo.
- pm = på begäranProcesser skapas endast när det behövs och avslutas efter process_idle_timeout. Detta sparar RAM-minne för sällsynta åtkomster (admin, staging, cron-slutpunkter), men kan leda till förlust av RAM-minne vid plötsliga toppar. Kallstarter och högre latens. Jag använder det därför selektivt och med en generös backlog.
- pm = statisk: Ett fast antal processer. Perfekt om jag har en hård övre gräns och särskilt förutsägbara latenser (t.ex. L7-proxy framför ett fåtal men kritiska slutpunkter). RAM-kravet är tydligt beräkningsbart, men oanvända processer binder upp minne.
Jag bestämmer vilket läge som passar profilen för varje pool. Jag brukar använda dynamiskt för frontends med varierande belastning, ondemand för utility-pooler och statiskt för dedikerade, latenskritiska tjänster.
Bestäm pm.max_children korrekt
Den viktigaste hävstången är pm.max_barn, eftersom detta värde definierar hur många förfrågningar som kan köras samtidigt. Jag beräknar startstorleken med hjälp av tumregeln: (fritt tillgängligt RAM - 2 GB reserv) dividerat med det genomsnittliga minnet per PHP-process. Som ett grovt antagande använder jag 40-80 MB per process och börjar initialt med 200-300 processer på en 32 GB host. Under livebelastning ökar eller minskar jag gradvis och kontrollerar om väntetiden för Kö sjunker och felfrekvensen minskar. Om du vill fördjupa dig kan du hitta bakgrundsinformation om start- och gränsvärden på Optimera pm.max_children.
Koordinera start-, reserv- och backlog-värden
Jag ställer in pm.start_servers till cirka 15-30 procent av pm.max_children så att tillräckligt många processer är tillgängliga vid starten och det inte blir några kallstarter. Med pm.min_spare_servers och pm.max_spare_servers definierar jag ett rimligt fönster för lediga processer så att nya förfrågningar inte väntar och samtidigt inte onödigt tomgångsminne binds upp. Listen.backlog är särskilt viktig: Denna kärnbuffert håller kortvarigt ytterligare anslutningsförsök när alla arbetare är upptagna. Vid belastningstoppar sätter jag höga värden (t.ex. 65535) så att kö inte stannar före FPM-poolen. Mer djupgående bakgrundsinformation om samspelet mellan webbservern, uppströms och buffertar finns i översikten över Köbildning på webbserver.
Begränsa körtiderna för begäran och återanvänd processer
Jag förhindrar smygande minnesstörningar med pm.max_förfrågningar, som startar om varje process efter X förfrågningar. Diskreta applikationer fungerar ofta bra med 500-800, men om jag misstänker minnesläckage minskar jag till 100-200 och observerar effekten. Dessutom kapslar request_terminate_timeout in avvikelser genom att avsluta extremt långvariga förfrågningar efter en fast tid. Konsistens är viktigt: Jag håller PHP:s max_execution_time och webbserverns timeouts i samma korridor så att det ena lagret inte avslutas tidigare än det andra. Denna interaktion håller Arbetare fri och skyddar poolen från överbelastning.
Gör köer synliga: Loggar och mätvärden
Jag läser regelbundet FPM-loggar och är uppmärksam på max antal barn som nås, eftersom denna post indikerar att den övre gränsen för processerna har nåtts. Samtidigt övervakar jag lyssningskön, som avslöjar en ökande eftersläpning i inmatningsbufferten. I kombination med request_slowlog_timeout får jag stackspår för långsamma punkter i koden och isolerar databas- eller API-bromsar. Jag korrelerar upstream_response_time från webbserverloggarna med request_time och statuskoder för att begränsa källan till långa svarstider. Detta gör det möjligt för mig att känna igen om flaskhalsen i PHP-FPM Databas eller uppströmsnätverket.
Profiler för arbetsbelastning: CPU-bunden kontra IO-bunden
För CPU-tunga processer skalar jag Parallellism Jag är försiktig och orienterar mig nära vCPU-numret, eftersom ytterligare processer knappast ger någon genomströmning. Om det huvudsakligen är en IO-belastning med databasåtkomst eller externa API:er kan jag tillåta fler processer så länge RAM-budgeten är tillräcklig. E-handelskassor drar nytta av längre timeouts (t.ex. 300 s) för att kunna slutföra betalningsmetoder utan avbokningar. Jag fångar upp flash-försäljning genom att sätta listen.backlog högt och öka reservfönstret. Information om balansen mellan antalet processer och värdprestanda finns i guiden till PHP-Workers som flaskhals.
Provberäkningar och dimensionering
Jag beräknar först minnet per process och härleder sedan en förnuftig Övre gräns av. Jag testar sedan under verklig belastning och observerar om kön minskar och genomströmningen ökar. Konservativa startvärden minskar risken för swapping och håller svarstiden jämn. Jag förfinar sedan i små steg för att vara säker på att inte märka av några biverkningar. Följande tabell ger vägledning om startvärden och effekter på Kö.
| Parametrar | Effekt | Startvärde (exempel) | Ledtråd |
|---|---|---|---|
| pm.max_barn | Max. samtidiga Processer | 200-300 (med 32 GB) | Jämför med RAM-budget och processstorlek |
| pm.start_servers | Initialt antal anställda | 15-30 % från max_children | Undvik kallstarter, men håll nere tomgångskörningen till ett minimum |
| pm.min_spare_servers | Gratis Arbetare Minimum | z. B. 20 | Direkt införande av nya förfrågningar |
| pm.max_spare_servers | Fri arbetare Maximalt | z. B. 40 | Begränsa RAM-förbrukningen för inaktiva processer |
| listen.backlog | Kernel-buffert för anslutningsförsök | 65535 | Dämpa belastningstoppar och minska avbrotten i anslutningen |
| pm.max_förfrågningar | återvinning Intervall | 500-800, med läckage 100-200 | Minimera minnesförluster och hängningar |
| begäran_avsluta_timeout | Hård gräns för begäran | 300-600 s | Överensstämmer med timeouts för PHP och webbserver |
Praktiska mallar för PHP FPM-pooler
För en butik med många läsaccesser ställer jag in måttlig Processsiffror och öka reservfönstret så att förfrågningar inte hamnar i kö. För innehållssidor med cachning räcker det ofta med betydligt färre arbetare så länge NGINX eller Apache levererar statiskt innehåll på ett effektivt sätt. Jag separerar multi-pool-konfigurationer enligt applikationsdelar som har olika minnesprofiler så att ingen tung pool tränger undan de andra. Jag definierar separata pooler med sina egna timeout-regler för cron- eller köarbetare. Det är så här jag håller den interaktiva Trafik gratis och saktar inte ner några användaråtgärder.
Timeouts för webbserver, uppströms och sockets
Jag anser att FastCGI och proxy timeouts från Nginx eller Apache i samma fönster som FPM:s timeouts så att inget lager avslutas för tidigt. Jag föredrar Unix-sockets framför TCP om båda tjänsterna körs på samma värd, eftersom latensen förblir minimal. För distribuerade konfigurationer använder jag TCP med stabila keepalive-värden och en tillräckligt stor anslutningspool. För hög parallellitet synkroniserar nginx worker_connections och FPM:s backlog-värden. Detta säkerställer att omdirigeringar förblir snabba och jag undviker tomgångstid på grund av för täta anslutningar. uppströms-begränsningar.
Caching, OPCache och databas som hävstänger
Jag löser många serverproblem genom att reducera dyra operationer och minimera Svarstid lägre. Jag slår på OPCache, ökar minnesgränsen för cachen på ett förnuftigt sätt och säkerställer en hög träfffrekvens för cachen. För återkommande resultat använder jag applikationscaching så att PHP-processer slutförs snabbare. På databassidan optimerar jag långsamma queries och aktiverar query caches som är lämpliga för det system som används. Varje millisekund som sparas minskar belastningen på Kö och ökar genomströmningen per arbetare.
Säkra nödmekanismer och omstarter
Jag aktiverar emergency_restart_threshold och emergency_restart_interval så att FPM-mastern startar om om alltför många barn kraschar i snabb följd. Denna kontrollerade omstart förhindrar kedjereaktioner och håller tjänsten tillgänglig. Samtidigt sätter jag tydliga gränser för minne och antal processer för att förhindra eskalering. Hälsokontroller på uppströmssidan tar automatiskt bort felaktiga backends från poolen och minskar felfrekvensen. Detta håller Tillgänglighet medan jag undersöker den verkliga orsaken.
Finjustera operativsystemets och systemd:s begränsningar
Så att listen.backlog faktiskt träder i kraft, justerar jag kärngränserna. OS-värdet net.core.somaxconn måste vara minst lika högt som den inställda backloggen, annars skär systemet av kön. Jag kontrollerar också antalet tillåtna filbeskrivare: I FPM-poolen kan jag ställa in rlimit_files, på tjänstenivå säkerställer jag LimitNOFILE (systemd) och på kärnnivå fs.file-max. Webbservern behöver liknande reserver så att den inte når sina gränser tidigare.
För mer stabila latenser minskar jag vm.swappiness, så att kärnan inte förskjuter aktivt använda minnessidor i förtid. I latens-kritiska konfigurationer avaktiverar jag Transparenta stora sidor, för att undvika långa sidfel. Om FPM körs via TCP synkroniserar jag även parametrarna net.ipv4.tcp_max_syn_backlog och reuse/keepalive. Sådana OS-detaljer verkar oansenliga, men de avgör om köer smidig löper ut eller om anslutningar redan avvisas före FPM.
Mät minnesbelastning per process
Istället för att göra generella uppskattningar mäter jag Real konsumtion per arbetare under verklig belastning. Jag använder verktyg som ps, smem eller pmap, filtrerar för php-fpm-barn och medelvärdet för RSS-värdena medan förfrågningar körs. Det är viktigt att ta hänsyn till den delade OPCache-användningen: delat minne räknas inte flera gånger. Jag härleder pm.max_children från det genomsnittliga värdet och planerar också en reserv så att maskinen inte stöter på en flaskhals även under toppar. Swapping lutar.
Jag upprepar denna mätning efter funktions- eller releaseändringar. Nya funktioner, fler beroenden eller ändringar i ramverk kan öka fotavtrycket per process avsevärt. På så sätt hålls antalet processer realistiskt och kön kort.
PHP FPM-status, ping och live-mätvärden
För en snabb bedömning av situationen aktiverar jag pm.status_path och en Ping slutpunkt (ping.path/ping.response). Jag kan se nyckeltal som accepterad anslutning, lyssningsköns längd, lediga/upptagna processer, max antal barn som nås och deras framsteg. Jag läser dessa värden med jämna mellanrum och sätter tröskelvärden: om listen queue ökar permanent ökar jag antingen antalet processer eller eliminerar orsaken till långsamma förfrågningar. Om max barn som nås hoppar upp medan inaktiviteten förblir låg är poolen för liten eller blockerad av långdistanslöpare.
Jag separerar också pooler med olika profiler så att spikar inom ett område (t.ex. API-import) inte får den interaktiva trafiken att gå på knäna. För diagnostiska fall ökar jag tillfälligt log_level och låter slowlog fånga fler prover, men minskar den sedan igen för att hålla I/O-belastningen låg.
Uppladdningar, buffring och stora förfrågningar
Stora uppladdningar kan binda upp arbetare i onödan om PHP måste läsa förfrågningens kropp först. Jag ser till att webbservern buffertar (t.ex. fastcgi_request_buffering för NGINX), så att FPM startar först när kroppen är klar. Detta innebär att ingen arbetare blockeras under uppladdningen. Jag använder client_max_body_size, post_max_size och max_input_time för att kontrollera hur stora och hur långa förfrågningar kan vara utan att äventyra slutpunkterna. Om det finns filer däremellan allokerar jag tillräckligt snabbt temporärt minne (SSD) för att undvika buffertstopp.
För slutpunkter med mycket stora datamängder (t.ex. export/import) definierar jag dedikerade pooler med egna timeouts och mindre parallellitet. Detta lämnar standardarbetarna fria och Kö av de viktiga användaråtgärderna.
Databasanslutningar och poolgränser
Även den bästa FPM-inställningen är värdelös om Databas tidigare begränsad. Jag anpassar det maximala antalet samtidiga PHP-processer till den faktiska tillgängliga DB-kapaciteten. För beständiga anslutningar eller anslutningspooler ser jag till att summan av alla pooler är under max_connections kvarstår. Om det finns många korta frågor hjälper det att begränsa PHP-parallellismen måttligt så att DB inte kastas mellan tusentals sessioner.
Långsamma transaktioner orsakar snabbt en eftersläpning i FPM-kön. Jag analyserar därför väntetider för lås, indexanvändning och frågeplaner. Varje minskning av DB-körtiden minskar omedelbart PHPDokumentets varaktighet och minskar kölängderna.
Release och utrullning utan spik
När jag rullar ut nya versioner undviker jag kalla cacher och processstormar. Jag använder Ladda om istället för hårda omstarter, så att befintliga arbetsförfrågningar avslutas på ett snyggt sätt (notera process_control_timeout). Jag värmer upp OPCache i ett tidigt skede genom att köra kritiska vägar en gång innan jag byter eller genom att arbeta med förladdning. Detta förhindrar att många arbetare parsar klassfiler samtidigt och Svarstid ökar med stormsteg.
Med blå/gröna eller canary-strategier ökar jag belastningen gradvis och övervakar statussidorna. Först när kön, felfrekvensen och fördröjningarna är stabila ökar jag andelen trafik. Detta kontrollerade tillvägagångssätt skyddar mot belastningstoppar under driftsättningen.
Specialiteter för containrar och virtuella maskiner
I containrar är den upplevda Total lagringsvolym ofta lägre än värdrapporterna. Jag anpassar pm.max_children strikt till cgroup-gränsen och planerar en reserv mot OOM-dödaren. Minnesgränserna i PHP (memory_limit) och fotavtrycket per process måste stämma överens, annars räcker det med en enda avvikelse för att avsluta containern.
Om det inte finns något byte i behållaren är det mer sannolikt med hårda avbokningar. Det är därför jag håller processerna konservativa, aktiverar återvinning och övervakar RSS-topparna i produktionsbelastningen. Flera smala pooler är ofta mer robusta här än en stor, monolitisk pool.
Kontrollerad nedbrytning och mottryck
Om Kö Jag förlitar mig på kontrollerad nedbrytning: Jag levererar medvetet 503 med omprövning efter för icke-kritiska slutpunkter i händelse av överbelastning, minskar dyra funktioner (t.ex. live-sökningar) och begränsar parallell åtkomst till hotspots. Detta håller systemet responsivt medan jag åtgärdar orsaken istället för att alla användare drabbas av timeouts.
Kortfattat sammanfattat
Jag tar med Kö för PHP-begäran under kontroll genom att på ett smart sätt anpassa antalet samtidiga processer till RAM-budgeten och typen av belastning. Höga backlog-värden buffrar toppar, timeouts på alla nivåer samverkar på ett snyggt sätt och återvinning tar bort krypande minnesproblem. Loggar och mätvärden visar mig om kön växer, var förfrågningar fastnar och när jag bör skärpa till mig. Med noggranna justeringar och riktad cachelagring minskar jag behandlingstiden per förfrågan och ökar genomströmningen. På så sätt levererar servrarna konsekvent och undviker dyra Tidsfrister i det dagliga livet.


