...

Apache Worker-modellen: Prefork, Worker en Event in vergelijking

Apache werkermodellen bepalen hoe de Apache HTTP Server verzoeken parallel verwerkt en bronnen gebruikt - specifiek via de MPM's Prefork, Worker en Event. In dit artikel laat ik zien hoe de drie modellen technisch verschillen, welke effecten ze hebben op Prestaties en schaalbaarheid en welke opstelling overtuigend is in echte scenario's.

Centrale punten

De volgende hoofdpunten geven je een snel overzicht van de belangrijkste verschillen en beslissingen rondom de drie MPM's; daarna ga ik dieper in op de details en geef ik je het volgende Praktische kennis.

  • VoorkurkProcesgebaseerd, hoge isolatie, hoge RAM-vereisten.
  • WerknemerThreads per proces, goed schaalbaar, gevoelig voor keep-alive.
  • EvenementGebeurtenislus ontkoppelt verbinding en verzoek, zeer efficiënt.
  • AfstemmenStartServers, ThreadsPerChild, MaxRequestWorkers specifiek.
  • HTTP/2: Werkt verstandig met Worker en Event, niet met Prefork.

Wat MPM's controleren in Apache

Ik gebruik de Multi-Processing Modules (MPM's) om te bepalen of Apache processen of threads gebruikt voor elke aanvraag en hoe de server Parallellisme biedt. Prefork creëert veel processen met elk één thread, Worker creëert een paar processen met veel threads, Event bouwt voort op Worker en ontkoppelt verbindingen van de daadwerkelijke verwerking. Deze keuze heeft een direct effect op geheugen, CPU-gebruik en latenties. Ik houd daarom altijd rekening met sessies, keep-alive, protocollen zoals HTTP/2 en de gebruikte modules. Als je MPM's negeert, geef je meetbare Prestaties en risico's op knelpunten.

Prefork: Procesisolatie en compatibiliteit

Prefork richt zich op individuele processen voor elke aanvraag en levert zo sterke Isolatie. Als één proces crasht, blijven de anderen onaangetast - dit verhoogt de fouttolerantie in het geval van onzuivere code of oude uitbreidingen. De prijs: Elk proces brengt zijn eigen overhead met zich mee, dus het RAM-verbruik per parallelle verbinding neemt toe. Met 100 gelijktijdige verzoeken worden er 100 processen aangemaakt, wat ik alleen acceptabel vind bij een lage tot gemiddelde belasting. Ik gebruik Prefork voornamelijk wanneer ik modules zonder thread safety moet gebruiken of wanneer legacy CGI scripts een hoog geheugengebruik vereisen. Scheiding vereisen.

Werker: threads en hoog parallellisme

In het worker model voeren individuele processen meerdere threads uit, waardoor er minder geheugen nodig is per verzoek. vermindert. Deze architectuur maakt aanzienlijk meer gelijktijdigheid op dezelfde hardware mogelijk en is geschikt voor hoge toegangsnummers. Lange keep-alive verbindingen kunnen echter threads en dus blokcapaciteit in beslag nemen. In schone, thread-veilige setups - bijvoorbeeld met PHP-FPM - bereik ik zeer goede RPS-waarden met Worker bij matig RAM-gebruik. Ik gebruik Worker als ik een efficiënte, thread-gebaseerde Schalen en keep-alive wordt verstandig gecontroleerd.

Gebeurtenis: Niet-blokkerende keep-alive strategie

Event is gebaseerd op het worker model, maar elimineert de keep-alive zwakte met een Gebeurtenis lus. Een thread verwerkt alleen het eigenlijke verzoek; een apart mechanisme is verantwoordelijk voor het onderhouden van de verbinding. Hierdoor blijven er threads vrij en verwerkt de machine meer gelijktijdige sessies met een lage latency. Event is vooral indrukwekkend voor HTTP/2 verbindingen, omdat multiplexing en lange verbindingen lopen zonder threads te verspillen. In moderne opstellingen begin ik met Event als Standaard basis en pas deze alleen aan als modules of oudere vereisten hiermee in strijd zijn.

Vergelijking van de MPM's in tabelvorm

De volgende tabel vat de belangrijkste verschillen samen, zodat ik het in één oogopslag kan zien beoordelen welk model past bij de belasting en de situatie van de module. Voordat ik overschakel, controleer ik altijd de threadveiligheid van alle modules en de verwachte verbindingsduur. Vervolgens wijs ik MaxRequestWorkers, ThreadsPerChild en andere limieten toe aan de beschikbare bronnen. De tabel helpt me om initiële aannames te doen, maar vervangt geen belastingtests onder echte omstandigheden. Vooral voor events is het de moeite waard om te meten met lange keep-alive fases en HTTP/2 om de Voordelen zichtbaar.

MPM Processen/Reads RAM-verbruik betrouwbaarheid Typisch gebruik
Voorkurk 1 thread per proces Hoog Hoog (goede isolatie) Lage/middelmatige belasting, modules zonder thread-veiligheid, klassieke CGI
Werknemer Meerdere threads per proces Medium Medium Hoge belasting met thread-safe stack, bijv. PHP-FPM
Evenement Draden + gebeurtenissenlus Laag Hoog Zeer hoge belasting, lange verbindingen, HTTP/2

Ik lees uit de tabel: Prefork scoort met afscherming, Worker voor efficiëntie en Event voor maximaal gebruik met gelijktijdige verbindingen. Ik gebruik Event voor nieuwe projecten, mits er geen incompatibiliteiten zijn. Prefork kan nog steeds nuttig zijn voor stabiele legacy-stacks. Wie net migreert, boekt vaak aanzienlijke vooruitgang met Worker. Uiteindelijk blijft de keuze een Afwegen van modules, verkeersprofiel en hardware.

Prestaties meten: Benchmarks en meetgegevens

Zonder meting blijft elke MPM-beslissing een Veronderstelling. In vergelijkende tests levert Worker tot ongeveer 50 % meer aanvragen per seconde dan Prefork onder hoge belasting; Event neemt ook toe, vooral tijdens lange keep-alive fasen. Er zijn duidelijke verschillen in termen van geheugen: met ongeveer 1000 gelijktijdige verbindingen komen Prefork setups ruwweg uit op 2-4 GB RAM, Worker op 1-2 GB, Event meestal onder 1 GB. Ik controleer niet alleen de RPS, maar ook de tijd tot de eerste byte, 95e/99e percentielen en foutpercentages. Het belastingsprofiel van de applicatie is cruciaal, omdat korte, snelle verzoeken zich anders gedragen dan streaming of WebSockets.

Uitleg over tuningparameters: StartServers, ThreadsPerChild, MaxRequestWorkers

Ik begin met conservatieve waarden en schaal op tot ik de gewenste waarde heb bereikt. Gebruik voldoen. Voor Prefork stel ik MaxRequestWorkers in op basis van het beschikbare geheugen en de procesgrootte; voor Worker en Event plan ik ThreadsPerChild en het aantal processen zo dat ThreadsPerChild × Processes = MaxRequestWorkers. Ik zorg voor voldoende buffer zodat belastingspieken niet leiden tot 503 fouten. Een schone StartServers waarde voorkomt onnodige forks bij een koude start. Als je dieper wilt graven, kun je achtergrondkennis vinden op de Threadpool-optimalisatie, die direct overgezet kunnen worden naar Apache opstellingen.

# Voorbeeld: Gebeurtenis (Debian/Ubuntu)
a2dismod mpm_prefork mpm_worker
a2enmod mpm_event
systemctl herstart apache2

# Maak verstandig gebruik van worker threading
# /etc/apache2/mods-available/mpm_event.conf
Serverlimiet 16
Start servers 4
ThreadsPerChild 50
MaxRequestWorkers 800
MaxConnectiesPerKind 0

Vervolgens controleer ik het effect met benchmarks en controleer ik of de CPU voldoende werk zonder te verdrinken in contextwisselingen. Tegelijkertijd houd ik RAM trends, swap activiteit en open bestandsdescriptors in de gaten. Als wachtrijen zichtbaar vol raken, verhoog ik voorzichtig MaxRequestWorkers of verkort ik keep-alive tijden. Als alles goed draait, maak ik een back-up van de configuratie en documenteer ik de Grenswaarden.

Keep-Alive, HTTP/2 en Thread-Contention

Keep-Alive vermindert TCP handshakes, maar kan threads binden - vooral met de Worker MPM, die verbindingen direct op threads plaatst. Event lost juist dit effect op door de verbinding via een event-lus tot stand te brengen. wikkelt af en threads alleen voor actief werk. Voor HTTP/2 gebruik ik daarom workers of events, omdat anders multiplexing wordt vertraagd. In de praktijk houd ik graag de wachtrijlengte in de gaten en controleer ik of „thread retention“ merkbaar is. Ik heb hier tips voor in het artikel over Draad-opname die ik gebruik voor meer diepgaande analyses.

Ik pas KeepAliveTimeout ook aan de applicatie aan zodat inactieve verbindingen geen invloed hebben op de Capaciteit niet binden. De ideale instelling verschilt tussen API's, klassieke LAMP-pagina's en HTTP/2-gebaseerde frontends met veel assets. Als er veel inactieve tijd is, verlaag ik de time-out en verhoog ik MaxRequestWorkers iets. Als ik veel korte verzoeken verwacht, houd ik Keep-Alive matig om TCP overhead te besparen. Als er wachttijden optreden, schakel ik over naar Event of stel ik extra Instanties naar.

Praktische scenario's en het kiezen van het juiste model

Voor legacy apps met risicovolle modules gebruik ik Prefork en profiteer ik van hoge afscherming. Met moderne PHP-FPM-architectuur met veel gelijktijdige verbindingen levert Worker al zeer goede resultaten. Event verlaagt de latency verder en schaalt netjes met lange sessies, WebSockets en HTTP/2. Op gedeelde hostings of met onduidelijke codestatus ben ik veiliger met Prefork, terwijl ik op VPS en dedicated hardware meestal de voorkeur geef aan Event. Als je alternatieven voor Apache overweegt, kun je meer informatie vinden in de compacte Webserver vergelijken aanvullende besluitvormingshulpen voor Nginx en LiteSpeed, die ik controleer afhankelijk van de situatie.

Het evenement loont tijdens verkeerspieken met een burst-karakter, omdat threads niet inactief zijn. blijven. Voor apps die veel CPU gebruiken, beperk ik MaxRequestWorkers om de machine niet te overbelasten. Als RAM schaars is, verban ik Prefork en geef ik voorrang aan Workers/Event. In multi-tenant omgevingen scheiden containers of cgroups de services zodat workers/events hun potentieel kunnen benutten. Uiteindelijk bevestigt de meting welk model in je eigen stack de laagste Latency benodigdheden.

Configuratie op Ubuntu/Debian in de praktijk

Ik activeer en deactiveer MPM's specifiek, test het effect en behoud rollback opties klaar. Onder Debian/Ubuntu gebruik ik de bekende commando's en controleer dan de statusuitvoer. Vervolgens pas ik de mpm_*.conf bestanden aan en log de wijzigingen in versie bij. Voor de go-live simuleer ik belastingspieken om deadlocks of geheugenknelpunten in een vroeg stadium te herkennen. Pas als de foutentellers en percentielen correct zijn, neem ik de Waarden in productie.

# Prefork inschakelen
a2dismod mpm_worker mpm_event
a2enmod mpm_prefork
systemctl herstart apache2

# Werker inschakelen
a2dismod mpm_prefork mpm_event
a2enmod mpm_worker
systemctl herstart apache2

# Gebeurtenis inschakelen
a2dismod mpm_prefork mpm_worker
a2enmod mpm_event
systemctl herstart apache2

# Bewaking
apachectl status
htop
journalctl -u apache2 -f

Ik controleer parallel de foutenlogboeken om snel problemen met draadbeveiliging te identificeren. Zoek. Voor HTTP/2 controleer ik of het protocol correct is onderhandeld en of de TLS-configuratie correct is. Als er merkbare latenties zijn, vergelijk ik afwisselend prefork/worker/event en houd ik de RAM-ontwikkeling in de gaten. Als de balans niet goed is, pas ik KeepAlive, het aantal threads en limieten aan. Hierdoor kan ik betrouwbare reactietijden bereiken zonder Overboeking.

Schroefdraadveiligheid en modulecompatibiliteit

De belangrijkste controle voordat wordt overgeschakeld van Prefork naar Worker/Event is de Veiligheid op draad van alle modules. Klassiek: mod_php is historisch nauw verbonden met Prefork; in moderne stacks gebruik ik in plaats daarvan PHP-FPM via proxy_fcgi, zodat Apache zelf thread-gebaseerd kan schalen. Filter- en auth-modules, zelfgeschreven modules of integraties (bijv. beeldverwerking) moeten ook als „thread safe“ worden beschouwd. Ik controleer de geladen modules, analyseer release notes en voer een crash- en raceconditietest uit onder belasting. Voor HTTP/2 geldt: Met Prefork is het praktisch geen optie - workers/events zijn de Voorwaarde, zodat multiplexing en prioritering werken.

Capaciteitsplanning: realistisch het opslagbudget berekenen

Ik dimensioneer MaxRequestWorkers niet „op gevoel“, maar op basis van meetbare proces- en draadmaten. Procedure:

  • Voer een testbelasting uit en meet vervolgens de residente setgrootte (RSS) per Apache-proces.
  • Denk aan de extra overhead per thread voor workers/events.
  • Plan buffers voor kernel, pagina cache, TLS sessie cache, log buffer en upstreams.
# Procesgrootte schatten (voorbeeld)
ps -ylC apache2 --sort:rss | awk '{sum+=$8} END {print "RSS (kB) totaal:",sum}'
ps -L -p  -o pid,tid,psr,stat,rss,cmd
pmap -x  | tail -n 1 # Totaalbedrag per proces

Rekenvoorbeeld: Een gebeurtenisproces neemt 25 MB in beslag, threads hebben gemiddeld 1 MB nodig. Met 16 processen en 50 threads resulteert dit ruwweg in 16 × 25 MB + 800 × 1 MB ≈ 1,2 GB. Ik stel MaxRequestWorkers = 800 in, laat 30-40 % RAM vrij en schaal op na de meting. Als je Prefork gebruikt, bereken dan gewoon „Procesgrootte × MaxRequestWorkers“ en blijf Conservatief.

Limieten van besturingssystemen, backlogs en descriptors

Apache kan alleen zo snel zijn als het onderliggende platform. Ik controleer regelmatig drie punten:

  • Bestandsdescriptors: Een thread/proces opent sockets, bestanden en pijpen. Ik verhoog LimitNOFILE via systemd en controleer de overdracht.
  • Achterstand accepteren: Voor verbindingsuitbarstingen vergroot ik ListenBacklog en zorg ik voor geschikte kernelbacklogs.
  • Socket/timeout afstemmen: Stel RequestReadTimeout, Timeout en KeepAliveTimeout specifiek in om „langzame clients“ te beperken.
# systemd overschrijven
systemctl bewerken apache2
[Service]
LimitNOFILE=65536

# Kernelparameters (tijdelijk)
sysctl -w net.core.somaxconn=4096

# Apache: Backlog en timeouts
Luister 0.0.0.0:443
Luisterachterstand 1024
Time-out 60
RequestReadTimeout header=10-20,MinRate=1 body=10,MinRate=500
KeepAliveTimeout 5
MaxKeepAliveRequests 100

Ik geef er de voorkeur aan om de time-outs iets strenger te houden en de foutpercentages in de gaten te houden. Als er legitiem lange uploads worden verwacht, pas ik de waarden specifiek aan per VirtualHost op.

Graceful reloads, implementaties en containers

Tijdens het gebruik geef ik de voorkeur aan herladen zonder bestaande verbindingen te verbreken. apachectl -k sierlijk of systemctl reload herlaadt configuraties, maar laat lopende verzoeken netjes verlopen - voor prefork per proces, voor worker/event per thread. In containeromgevingen plan ik kleinere ServerLimit/ThreadsPerChild zodat pods kunnen worden start en afsluiten. Ik let op cgroup quota: als CPU tijd of RAM gelimiteerd zijn, moet MaxRequestWorkers overeenkomstig lager zijn, anders verschuift de latency naar het 95e/99e percentiel.

Proxy/upstream-instellingen correct dimensioneren

Veel Apache-instanties beëindigen TLS en proxyen dan naar PHP-FPM, app-servers of microservices. Ik koppel frontend capaciteit (MaxRequestWorkers) aan de upstream pools: Voor PHP-FPM zijn pm.max_children en pm.max_requests de harde bovengrens. Ik houd de verhouding zo dat Apache niet significant meer gelijktijdige verzoeken accepteert dan de upstreams aankunnen. Time-outs. Ik stel expliciet timeouts in voor proxy_fcgi en proxy_http en controleer of keep-alive nuttig is voor upstream of alleen maar bronnen vastzet.

Bewaking en diagnose met het scorebord

De mod_status uitvoer laat zien hoe goed de geselecteerde MPM werkt. Ik let op de verhoudingen van de volgende statussen: Lezen (inkomende headers), Verzenden (antwoord wordt verzonden), Keepalive (open verbinding zonder arbeid), Wachten (gratis). Hoge percentages Keepalive in Worker geven gebonden threads aan - Event elimineert precies dat. Permanente Lezen kan het gevolg zijn van trage clients of onjuiste RequestReadTimeout-waarden. Veel Sluiten/vastleggenDe toestanden onder piekbelasting duiden op te kleine threadpools of I/O-knelpunten bij het loggen.

Veiligheid en robuustheid: Slowloris & Co.

De combinatie van Event-MPM, strakke KeepAliveTimeouts en RequestReadTimeout helpt tegen „Slowloris“-achtige aanvalspatronen. Hoewel Prefork beschermt tegen modulecrashes door procesisolatie, blijft het gevoelig voor RAMUitputting met veel verbindingen. Ik combineer limieten op webserverniveau met upstream WAF/snelheidslimieten zodat Apache niet in de eerste plaats geconfronteerd wordt met miljoenen half-open sessies. Ik analyseer logs tot 95ste/99ste percentielen omdat aanvallen de distributiestaarten opblazen.

Standaard distributie en typische struikelblokken

Event is nu standaard op veel Debian/Ubuntu-installaties. Desondanks zijn de standaardwaarden vaak conservatief (bijvoorbeeld ThreadsPerChild 25-50). Ik verhoog deze alleen na metingen. Veel voorkomende fouten:

  • MaxRequestWorkers hoger dan de beschikbare bestandsdescriptors.
  • Niet gesynchroniseerde limieten tussen Apache- en PHP-FPM/App-servers.
  • KeepAliveTimeout te hoog voor werknemers met veel mobiele clients.
  • Ontbrekende buffer voor log I/O - blokrotatietaken korte termijn.

Ik documenteer doelwaarden (CPU-gebruik, RAM, RPS, P95) en sla een versie van de werkconfiguratie op. Alleen dan is de Uitrolbaar.

Kort samengevat

Prefork levert sterke Isolatie voor legacy stacks, maar kost veel geheugen. Worker biedt een goed centrum met threads per proces en schaalt netjes zolang Keep-Alive niet onnodig vastloopt. Event scheidt verbinding en verwerking, verhoogt het gebruik en toont zijn kracht met HTTP/2 en lange sessies. Ik meet systematisch, pas limieten aan en kies de MPM die past bij de code, het verkeersprofiel en de hardware. Met clean tuning, duidelijke meetdoelen en gerichte monitoring haalt Apache het maximale uit elk van de drie modellen. Prestaties uit.

Huidige artikelen