...

Apache Worker-modeller: Prefork, Worker och Event i jämförelse

Apache Worker-modeller avgör hur Apache HTTP Server behandlar förfrågningar parallellt och utnyttjar resurser - särskilt via MPM:erna Prefork, Worker och Event. I den här artikeln kommer jag att visa hur de tre modellerna skiljer sig åt tekniskt, vilka effekter de har på Effekt och skalning och vilket upplägg som är övertygande i verkliga scenarier.

Centrala punkter

Följande punkter ger dig en snabb överblick över de viktigaste skillnaderna och besluten kring de tre MPM:erna; sedan går jag in mer i detalj och ger Praktisk kunskap.

  • PreforkProcessbaserad, hög isolering, höga RAM-krav.
  • ArbetareTrådar per process, bra skalning, känslig för keep-alive.
  • EvenemangEvenemangsslingan kopplar bort anslutning och begäran, mycket effektivt.
  • TuningStartServers, ThreadsPerChild, MaxRequestWorkers specifikt.
  • HTTP/2: Fungerar bra med Worker och Event, men inte med Prefork.

Vad MPM kontrollerar i Apache

Jag använder MPM:erna (Multi-Processing Modules) för att avgöra om Apache använder processer eller trådar för varje förfrågan och hur servern Parallellism tillhandahåller. Prefork skapar många processer med en tråd vardera, Worker skapar ett fåtal processer med många trådar, Event bygger vidare på Worker och frikopplar anslutningar från den faktiska bearbetningen. Detta val har en direkt effekt på minne, CPU-användning och latenser. Jag tar därför alltid hänsyn till sessioner, keep-alive, protokoll som HTTP/2 och de moduler som används. Om du ignorerar MPM:er ger du bort mätbara Prestanda och riskerar flaskhalsar.

Prefork: Processisolering och kompatibilitet

Prefork fokuserar på individuella processer för varje förfrågan och levererar därmed starka Isolering. Om en process kraschar påverkas inte de andra - detta ökar feltoleransen i händelse av oren kod eller gamla tillägg. Priset: Varje process ger sin egen overhead, så RAM-förbrukningen per parallell anslutning ökar. Med 100 samtidiga förfrågningar skapas 100 processer, vilket jag bara tycker är acceptabelt med låg till medelhög belastning. Jag använder Prefork främst när jag måste använda moduler utan trådsäkerhet eller när äldre CGI-skript kräver hög minnesanvändning. Separation kräver.

Worker: Trådar och hög parallellism

I arbetsmodellen kör enskilda processer flera trådar, vilket minskar minnesbehovet per begäran. minskar. Denna arkitektur tillåter betydligt mer samtidighet på samma maskinvara och är lämplig för höga accessnummer. Långa keep-alive-anslutningar kan dock binda upp trådar och därmed blockera kapacitet. I rena, trådsäkra konfigurationer - till exempel med PHP-FPM - uppnår jag mycket bra RPS-värden med Worker med måttlig RAM-användning. Jag använder Worker när jag behöver en effektiv, trådbaserad Skalning och keep-alive kontrolleras på ett förnuftigt sätt.

Händelse: Icke-blockerande keep-alive-strategi

Event är baserad på worker-modellen, men eliminerar keep-alive-svagheten med en Evenemangsslinga. En tråd behandlar bara den faktiska begäran; en separat mekanism ansvarar för att upprätthålla anslutningen. På så sätt frigörs trådar och maskinen kan bearbeta fler samtidiga sessioner med låg latens. Event är särskilt imponerande för HTTP/2-anslutningar, eftersom multiplexering och långa anslutningar körs utan att slösa bort trådar. I moderna konfigurationer börjar jag med Event som Standard bas och endast anpassa om moduler eller äldre krav står i konflikt med detta.

Jämförelse av MPM i tabellform

I följande tabell sammanfattas de viktigaste skillnaderna så att jag kan se dem på ett överskådligt sätt bedöma vilken modell som passar lasten och modulsituationen. Innan jag byter kontrollerar jag alltid trådsäkerheten för alla moduler och den förväntade anslutningslängden. Sedan tilldelar jag MaxRequestWorkers, ThreadsPerChild och andra begränsningar till de tillgängliga resurserna. Tabellen hjälper mig att göra initiala antaganden, men ersätter inte belastningstester under verkliga förhållanden. Särskilt för evenemang är det värt att göra en mätning med långa keep-alive-faser och HTTP/2 för att fastställa Fördelar synlig.

MPM Processer/Trådar RAM-förbrukning tillförlitlighet Typisk användning
Prefork 1 tråd per process Hög Hög (god isolering) Låg/medelhög belastning, moduler utan trådsäkerhet, klassisk CGI
Arbetare Flera trådar per process Medium Medium Hög belastning med trådsäker stack, t.ex. PHP-FPM
Evenemang Trådar + händelseslinga Låg Hög Mycket hög belastning, långa anslutningar, HTTP/2

Jag läser från tabellen: Prefork gör mål med skärmning, Worker för effektivitet och Event för maximalt utnyttjande med samtidiga anslutningar. Jag använder Event för nya projekt, förutsatt att det inte finns några inkompatibiliteter. Prefork kan fortfarande vara användbart för stabila äldre stackar. De som bara migrerar uppnår ofta betydande framsteg med Worker. I slutändan är valet fortfarande en Väger upp från moduler, trafikprofil och hårdvara.

Mätning av prestanda: Benchmarks och mätetal

Utan mätning förblir varje MPM-beslut ett Antagande. I jämförande tester levererar Worker upp till cirka 50 % fler förfrågningar per sekund än Prefork under hög belastning; Event ökar också, särskilt under långa keep-alive-faser. Det finns tydliga skillnader när det gäller minne: med cirka 1000 samtidiga anslutningar slutar Prefork-konfigurationer ungefär med 2-4 GB RAM, Worker med 1-2 GB, Event vanligtvis under 1 GB. Jag kontrollerar inte bara RPS, utan även tid till första byte, 95:e/99:e percentiler och felfrekvenser. Applikationens belastningsprofil är avgörande, eftersom korta, snabba förfrågningar beter sig annorlunda än streaming eller WebSockets.

Tuning-parametrar förklarade: StartServers, ThreadsPerChild, MaxRequestWorkers

Jag börjar med konservativa värden och skalar upp tills jag når det önskade värdet. Användning träffas. För Prefork ställer jag in MaxRequestWorkers baserat på det tillgängliga minnet och processstorleken; för Worker och Event planerar jag ThreadsPerChild och antalet processer så att ThreadsPerChild × Processes = MaxRequestWorkers. Jag ser till att det finns tillräckligt med buffert så att belastningstoppar inte leder till 503-fel. Ett rent StartServers-värde förhindrar onödiga gafflar under kallstartförhållanden. Om du vill gräva djupare kan du hitta bakgrundsinformation på Optimering av trådpool, som kan överföras direkt till Apache-installationer.

# Exempel: Händelse (Debian/Ubuntu)
a2dismod mpm_prefork mpm_worker
a2enmod mpm_event
systemctl starta om apache2

# Utnyttja arbetartrådning på ett förnuftigt sätt
# /etc/apache2/mods-available/mpm_event.conf
Serverbegränsning 16
Starta servrar 4
TrådarPerBarn 50
MaxBegäranArbetare 800
MaxAnknytningarPerChild 0

Jag kontrollerar sedan effekten med benchmarks och ser om processorn är tillräckligt arbete utan att drunkna i kontextbyten. Samtidigt övervakar jag RAM-trender, swap-aktivitet och öppna filbeskrivare. Om köerna blir synligt fulla ökar jag försiktigt MaxRequestWorkers eller minskar keep-alive-tiderna. Om allt går som det ska tar jag en säkerhetskopia av konfigurationen och dokumenterar Gränsvärden.

Keep-Alive, HTTP/2 och Thread-Contention

Keep-Alive minskar antalet TCP-handskakningar, men kan binda trådar - särskilt med Worker MPM, som placerar anslutningar direkt på trådar. Event löser just denna effekt genom att upprätta anslutningen via en händelseslinga. lindar av och trådar endast för aktivt arbete. För HTTP/2 använder jag därför workers eller events, eftersom multiplexeringen annars saktas ned. I praktiken gillar jag att övervaka kölängden och kontrollera om „trådretention“ är märkbar. Jag har tips om detta i artikeln om Trådens fastsättning som jag använder för mer djupgående analyser.

Jag anpassar också KeepAliveTimeout till applikationen så att inaktiva anslutningar inte påverkar Kapacitet inte binda. Den perfekta inställningen skiljer sig mellan API:er, klassiska LAMP-sidor och HTTP/2-baserade frontends med många tillgångar. Om det finns mycket inaktiv tid sänker jag timeouten och ökar MaxRequestWorkers något. Om jag förväntar mig många korta förfrågningar håller jag Keep-Alive måttligt för att spara TCP-overhead. Om det uppstår väntetider byter jag till Event eller sätter upp ytterligare Instanser till.

Praktiska scenarier och val av rätt modell

För äldre appar med riskfyllda moduler använder jag Prefork och drar nytta av höga skärmning. Med modern PHP FPM-arkitektur med många samtidiga anslutningar levererar Worker redan mycket bra resultat. Event minskar latensen ytterligare och skalar rent med långa sessioner, WebSockets och HTTP/2. På delade hostings eller med oklar kodstatus är jag säkrare med Prefork, medan jag vanligtvis föredrar Event på VPS och dedikerad hårdvara. Om du funderar på alternativ till Apache kan du hitta mer information i den kompakta Jämförelse av webbservrar ytterligare beslutsstöd för Nginx och LiteSpeed, som jag kontrollerar beroende på situationen.

Evenemanget lönar sig under trafiktoppar med en burst-karaktär, eftersom trådarna inte är inaktiva. kvarstå. För CPU-tunga appar begränsar jag MaxRequestWorkers för att inte överbelasta maskinen. Om det är ont om RAM-minne bannlyser jag Prefork och prioriterar Workers/Event. I miljöer med flera hyresgäster separerar containrar eller cgroups tjänsterna så att Workers/Events kan förverkliga sin potential. I slutändan bekräftar mätningen vilken modell i din egen stack som har lägst Fördröjning förnödenheter.

Konfiguration på Ubuntu/Debian i praktiken

Jag aktiverar och avaktiverar MPM:er specifikt, testar effekten och behåller rollback-alternativ redo. Under Debian/Ubuntu använder jag de kända kommandona och kontrollerar sedan statusutmatningen. Sedan justerar jag mpm_*.conf-filerna och loggar versionsändringar. Före driftsättningen simulerar jag belastningstoppar för att tidigt upptäcka dödlägen eller flaskhalsar i minnet. Först när felräknarna och percentilerna är korrekta tar jag över Värden i produktion.

# Slå på prefork
a2dismod mpm_worker mpm_event
a2enmod mpm_prefork
systemctl starta om apache2

Slå på #-arbetaren
a2dismod mpm_prefork mpm_event
a2enmod mpm_worker
systemctl starta om apache2

# Växla på händelse
a2dismod mpm_prefork mpm_worker
a2enmod mpm_event
systemctl starta om apache2

# Övervakning
apachectl status
htop
journalctl -u apache2 -f

Jag övervakar felloggar parallellt för att snabbt kunna identifiera säkerhetsproblem i trådar. Hitta. För HTTP/2 kontrollerar jag om protokollet förhandlas korrekt och om TLS-konfigurationen är korrekt. Om det finns märkbara latenser jämför jag prefork/worker/event omväxlande och håller ett öga på RAM-utvecklingen. Om balansen inte är den rätta justerar jag KeepAlive, antalet trådar och limits. Detta gör att jag kan uppnå tillförlitliga svarstider utan att Överbokning.

Gängsäkerhet och modulkompatibilitet

Den viktigaste preliminära kontrollen innan du byter från Prefork till Worker/Event är Tråd säkerhet av alla moduler. Klassiskt: mod_php är historiskt nära kopplat till Prefork; i moderna stackar använder jag PHP-FPM via proxy_fcgi istället, så att Apache själv kan skala trådbaserat. Filter- och auth-moduler, egenskrivna moduler eller integrationer (t.ex. bildbehandling) måste också betraktas som „trådsäkra“. Jag kontrollerar de laddade modulerna, analyserar release notes och utför ett krasch- och race condition-test under belastning. Följande gäller för HTTP/2: Med Prefork är det praktiskt taget inte ett alternativ - workers/events är Förkunskapskrav, så att multiplexering och prioritering fungerar.

Kapacitetsplanering: realistisk beräkning av lagringsbudgeten

Jag dimensionerar inte MaxRequestWorkers „på känsla“, utan på basis av mätbara process- och gängstorlekar. Förfarande:

  • Kör testbelastningen och mät sedan RSS (Resident Set Size) per Apache-process.
  • Tänk på den extra overhead per tråd för workers/events.
  • Schemalägg buffertar för kärnan, sidcache, TLS-sessionscache, loggbuffert och uppströmmar.
# Uppskatta processens storlek (exempel)
ps -ylC apache2 --sort:rss | awk '{sum+=$8} END {print "RSS (kB) totalt:",sum}'
ps -L -p  -o pid,tid,psr,stat,rss,cmd
pmap -x  | tail -n 1 # Total summa per process

Beräkningsexempel: En händelseprocess upptar 25 MB, trådar kräver i genomsnitt 1 MB. Med 16 processer och 50 trådar blir resultatet ungefär 16 × 25 MB + 800 × 1 MB ≈ 1,2 GB. Jag sätter MaxRequestWorkers = 800, lämnar 30-40 % RAM fritt och skalar upp efter mätning. Om du använder Prefork beräknar du helt enkelt „Processstorlek × MaxRequestWorkers“ och behåller Konservativ.

Operativsystemets gränser, backlogs och deskriptorer

Apache kan bara vara lika snabb som den underliggande plattformen. Jag kontrollerar regelbundet tre punkter:

  • Filbeskrivningar: En tråd/process öppnar uttag, filer och rör. Jag ökar LimitNOFILE via systemd och verifierar överföringen.
  • Acceptera eftersläpning: För anslutningssvårigheter förstorar jag ListenBacklog och tillhandahåller lämpliga kernel backlogs.
  • Justering av uttag/timeout: Ställ in RequestReadTimeout, Timeout och KeepAliveTimeout specifikt för att motverka „långsamma klienter“.
# systemd åsidosätta
systemctl redigera apache2
[Service]
BegränsaNOFILE=65536

# Kärnparametrar (tillfälliga)
sysctl -w net.core.somaxconn=4096

# Apache: Backlog och timeouts
Lyssna 0.0.0.0:443
LyssnaBacklog 1024
Timeout 60
RequestReadTimeout header=10-20,MinRate=1 body=10,MinRate=500
KeepAliveTimeout 5
MaxKeepAliveRequests 100

Jag föredrar att hålla timeouts lite striktare och övervaka felfrekvenserna. Om man förväntar sig riktigt långa uppladdningar justerar jag värdena specifikt per Virtuell värd en.

Skonsamma omladdningar, driftsättningar och containrar

I drift föredrar jag omladdningar utan att bryta befintliga förbindelser. apachectl -k graciös eller systemctl reload laddar om konfigurationer, men låter pågående förfrågningar löpa ut på ett snyggt sätt - för prefork per process, för worker/event per tråd. I containermiljöer planerar jag mindre ServerLimit/ThreadsPerChild så att pods kan vara starta och avsluta. Jag är uppmärksam på cgroup-kvoter: Om CPU-tid eller RAM-minne begränsas måste MaxRequestWorkers vara motsvarande lägre, annars flyttas latensen till den 95:e/99:e percentilen.

Korrekt dimensionering av proxy/upstream-konfigurationer

Många Apache-instanser avslutar TLS och proxar sedan till PHP-FPM, appservrar eller mikrotjänster. Jag länkar frontend-kapacitet (MaxRequestWorkers) med uppströms pooler: För PHP-FPM är pm.max_children och pm.max_requests den hårda övre gränsen. Jag håller förhållandet så att Apache inte accepterar betydligt fler samtidiga förfrågningar än vad uppströmmarna kan hantera - annars kommer köer och Tidsfrister. Jag ställer in timeouts uttryckligen för proxy_fcgi och proxy_http och kontrollerar om keep-alive är användbart för uppströms eller bara binder upp resurser.

Övervakning och diagnostik med resultattavlan

Mod_status-utdata visar hur väl den valda MPM:n fungerar. Jag är uppmärksam på proportionerna av följande statusar: Läsning (inkommande rubriker), Sändning (svaret är överfört), Keepalive (öppen anslutning utan arbete), Väntar på (gratis). Höga andelar av Keepalive in Worker indikerar bundna trådar - Event eliminerar exakt det. Permanent Läsning kan bero på långsamma klienter eller felaktiga RequestReadTimeout-värden. Många Avslutning/LoggningTillstånden under toppbelastning indikerar trådpooler som är för små eller I/O-flaskhalsar i loggningen.

Säkerhet och robusthet: Slowloris & Co.

Kombinationen av Event-MPM, snäva KeepAliveTimeouts och RequestReadTimeout hjälper mot attackmönster av typen „Slowloris“. Även om Prefork skyddar mot modulkrascher genom processisolering, är det fortfarande känsligt för RAMUtmattning med många anslutningar. Jag kombinerar gränser på webbservernivå med WAF/rate-gränser uppströms så att Apache inte konfronteras med miljontals halvöppna sessioner från första början. Jag analyserar loggar till 95:e/99:e percentilerna eftersom attacker blåser upp distributionens svansar.

Standarddistribution och typiska stötestenar

Event är nu standard på många Debian/Ubuntu-installationer. Ändå är standardvärdena ofta konservativa (t.ex. ThreadsPerChild 25-50). Jag ökar bara dessa efter mätning. Frekventa fel:

  • MaxRequestWorkers högre än antalet tillgängliga filbeskrivare.
  • Osynkroniserade gränser mellan Apache- och PHP-FPM/App-servrar.
  • KeepAliveTimeout för hög för anställda med många mobila klienter.
  • Saknar buffert för logg-I/O - blockrotationsjobb kortsiktiga.

Jag dokumenterar målvärden (CPU-användning, RAM, RPS, P95) och sparar en version av arbetskonfigurationen. Först då är Utrullning.

Kortfattat sammanfattat

Prefork levererar starkt Isolering för äldre stackar, men kostar mycket minne. Worker erbjuder ett bra centrum med trådar per process och skalar rent så länge Keep-Alive inte binder upp i onödan. Event separerar anslutning och bearbetning, ökar utnyttjandegraden och visar sin styrka med HTTP/2 och långa sessioner. Jag mäter systematiskt, justerar gränser och väljer den MPM som passar koden, trafikprofilen och hårdvaran. Med en ren inställning, tydliga mätmål och fokuserad övervakning får Apache ut mesta möjliga av var och en av de tre modellerna. Effekt ut.

Aktuella artiklar