PHP OPcache gør mine scripts hurtigere, fordi PHP bruger den kompilerede byte-kode i hukommelsen og dermed sparer den nye parsing. I denne vejledning viser jeg, hvordan jeg OPcache Konfigurer, overvåger og finjusterer, så din applikation reagerer mærkbart hurtigere og roligt absorberer belastningsspidser.
Centrale punkter
- Bytecode-cache Reducerer CPU-belastning og I/O
- Parametre hvordan man vælger memory_consumption og max_accelerated_files målrettet
- Omgivelser Indstil differentieret: Dev, Staging, Produktion
- Overvågning til hitrate, belægning, evictions
- Udrulning og cache-flush rent indgreb
Sådan fungerer OPcache: Bytecode i stedet for re-kompilering
Ved hver forespørgsel læser PHP normalt filer, analyserer koden og opretter byte-kode, som Zend Engine udfører. OPcache sætter ind netop her og gemmer denne bytecode i den delte hukommelse, så efterfølgende forespørgsler starter direkte fra hukommelsen. Dette reducerer CPU-cyklusser og filadgang, hvilket mærkbart forkorter svartiderne. I typiske opsætninger opnår jeg dermed gevinster på mellem 30 og 70 procent, afhængigt af kodebasen og trafikprofilen. Det afgørende er, at cachen forbliver stor nok, og at de vigtigste scripts permanent gemmes i Hukommelse forbliver.
Kontroller og aktiver OPcache på Linux, Windows og Shared Hosting
Jeg starter altid med at kigge i phpinfo() og søger efter „Zend". OPcache“ samt nøgler som opcache.enable eller opcache.memory_consumption. Under Linux aktiverer jeg modulet via pakken php-opcache og en opcache.ini i conf.d-mappen. I Windows er det tilstrækkeligt at indtaste zend_extension=opcache i php.ini og genstarte webserveren. I shared hosting aktiverer jeg ofte OPcache via en brugerdefineret php.ini eller via kundemenuen. Ved flaskehalse tjekker jeg desuden Forøg PHP-hukommelsesgrænsen, så OPcache og PHP-FPM har nok Ressourcer modtaget.
De vigtigste kontakter forklaret på en forståelig måde
Med opcache.enable aktiverer jeg cachen for webforespørgsler, mens opcache.enable_cli styrer brugen til CLI-opgaver, hvilket er nyttigt ved arbejdskøer. Kernen udgøres af opcache.memory_consumption, som angiver den tilgængelige delte hukommelse i megabyte; for lavt dimensioneret fører til evictions og fornyet Samlinger. opcache.max_accelerated_files definerer, hvor mange filer der overhovedet må ende i cachen; denne værdi bør overstige projektets filantal på en fornuftig måde. Med opcache.validate_timestamps og opcache.revalidate_freq bestemmer jeg, hvor strengt OPcache kontrollerer ændringer i filer, fra meget dynamisk (udvikling) til meget sparsomt (produktion med manuel flush). Jeg sikrer kommentarer med opcache.save_comments=1, fordi mange værktøjer på DocBlocks er afhængige af.
Startværdier og profiler i sammenligning
For at sikre en problemfri start satser jeg på klare profiler til udvikling, staging og produktion. På den måde får jeg på den ene side hurtige feedbackcyklusser ved kodning og på den anden side pålidelig ydeevne i live-drift. Det er vigtigt, at du regelmæssigt kontrollerer og finjusterer disse startværdier i forhold til reelle målinger. Ved større WordPress-installationer planlægger jeg generøst med hukommelse og poster, fordi plugins og temaer kræver meget Filer . Den følgende tabel opsummerer fornuftige startværdier, som jeg derefter finjusterer på baggrund af hitrate og evictions.
| Indstilling | Udvikling | Staging/Test | Produktion |
|---|---|---|---|
| opcache.enable | 1 | 1 | 1 |
| opcache.enable_cli | 0 | 0–1 | 1 (ved CLI-opgaver) |
| opcache.memory_consumption | 128–256 MB | 256–512 MB | 256–512+ MB |
| opcache.interned_strings_buffer | 16–32 MB | 32–64 MB | 16–64 MB |
| opcache.max_accelererede_filer | 8.000–10.000 | 10.000–20.000 | 10.000–20.000+ |
| opcache.validate_timestamps | 1 | 1 | 0–1 (afhængigt af Deploy) |
| opcache.revalidate_freq | 0–2 s | 60–300 s | 300+ s eller 0 (med manuel kontrol) |
| opcache.save_comments | 1 | 1 | 1 |
| opcache.fast_shutdown | 1 | 1 | 1 |
Denne matrix er bevidst pragmatisk, fordi virkelige projekter vokser meget forskelligt. Jeg starter med disse værdier og observerer derefter hitraten, den belagte andel af den delte hukommelse og forekomsten af evictions. Ved tegn på pres øger jeg først opcache.memory_consumption i moderate trin. Derefter justerer jeg opcache.max_accelerated_files, indtil antallet af filer passer komfortabelt ind. Så forbliver Cache effektiv, og forespørgslerne forbliver jævnt hurtige.
Indstillinger efter miljø: Udvikling, staging, produktion
I udviklingen er hurtig feedback på kodeændringer vigtig, derfor sætter jeg validate_timestamps=1 og revalidate_freq meget lavt eller endda 0. På staging tester jeg realistisk belastning og sætter hukommelsen generøst, så resultaterne kommer tæt på den senere live-drift. I produktionen øger jeg testfrekvensen eller deaktiverer tidsstempler helt, hvis min implementering derefter tømmer cachen målrettet. For CLI-baserede arbejdere aktiverer jeg enable_cli=1, så tilbagevendende jobs også kan udføres af Bytecode-cache drage fordel af. Således skaber hvert miljø præcis den adfærd, jeg har brug for, uden overraskelser i reaktionstiderne.
Udvidede indstillinger, der ofte gør en forskel
Ud over de grundlæggende parametre findes der kontakter, som jeg kan bruge til at øge stabiliteten og sikkerheden og minimere bivirkninger:
- opcache.max_wasted_percentage: Definerer, fra hvilket fragmenteringsniveau OPcache igangsætter en intern genopbygning af hukommelsen. Ved stærkt skiftende kodebaser reducerer jeg værdien lidt for at have mindre „blandet“ hukommelse.
- opcache.force_restart_timeout: Periode i sekunder, efter hvilken OPcache foretager en tvungen genstart, hvis en genstart er påkrævet, men processer stadig er aktive. Dette forhindrer meget lange ventetider.
- opcache.file_update_protection: Beskyttelsesvindue i sekunder, hvor nyligt ændrede filer ikke straks caches. Dette hjælper mod halvskrevne filer under implementeringer eller på netværksdrev.
- opcache.restrict_api: Begrænser, hvilke scripts der må kalde opcache_reset() og statusfunktioner. I produktionen indstiller jeg dette strengt, så kun administrationsendepunkter har adgang.
- opcache.blacklist_filename: Fil, hvor jeg vedligeholder mønstre, der er udelukket fra cachen (f.eks. meget dynamiske generatorer). Det sparer plads til mere kritiske scripts.
- opcache.validate_permission og opcache.validate_root: Aktiv, når flere brugere/chroots er involveret. På denne måde forhindrer PHP, at cachelagret kode fra en kontekst bruges uautoriseret i en anden.
- opcache.use_cwd og opcache.revalidate_path: Styring af, hvordan OPcache identificerer scripts, når stier integreres via forskellige arbejdsmapper/symlinks. Ved release-symlinks tester jeg disse værdier specifikt for at undgå dobbeltcacher.
- opcache.cache_id: Hvis flere virtuelle værter deler den samme SHM (sjældent), adskiller jeg cachesene tydeligt ved hjælp af en entydig ID.
- opcache.optimization_level: Jeg lader det normalt være på standard. Kun i tilfælde af debugging-edgecases reducerer jeg midlertidigt optimeringspassene.
Preloading: Opbevaring af koden permanent i hukommelsen
Med PHP 7.4+ kan jeg via opcache.preload og opcache.preload_user indlæse og linke centrale framework- eller projektfiler, når serveren starter. Fordelen: Klasser er tilgængelige uden autoload-hits, og hot paths er tilgængelige med det samme. Et par praktiske regler:
- Preloading er især nyttigt ved store, stabile kodebaser (f.eks. Symfony, egne kernebiblioteker). I WordPress bruger jeg det med tilbageholdenhed, fordi Core/Plugins opdateres oftere.
- En preload-fil indeholder målrettede opcache_compile_file()-kald eller integrerer en autoloader, der definerede klasser på forhånd lader.
- Enhver kodeændring i preload-relevante filer kræver en genstart af PHP-FPM, så preload genopbygges. Det integrerer jeg fast i implementeringer.
- Jeg måler effekten separat: ikke alle koder drager fordel af det; forhåndsindlæsning bruger ekstra delt hukommelse.
JIT og OPcache: Fordele, begrænsninger, lagerpladsbehov
Siden PHP 8 findes Just-In-Time-Compiler (JIT), der styres via OPcache (opcache.jit, opcache.jit_buffer_size). For typiske web-workloads med I/O- og databasebelastning giver JIT ofte kun ringe gevinst. Ved kode med stor CPU-belastning (f.eks. billed-/databehandling) kan det være en mærkbar hjælp. Jeg gør således:
- Jeg aktiverer JIT konservativt og måler reelle brugermetrikker samt CPU-profiler. Blind aktivering øger hukommelsesbehovet og kan udløse edgecases.
- Jeg dimensionerer JIT-bufferen afhængigt af CPU-belastede ruter. For små buffere giver ingen merværdi, for store buffere fortrænger bytecode.
- Hvis hitraten eller SHM-belægningen lider under det, prioriterer jeg OPcache frem for JIT. Bytecode-cache er for de fleste websteder det vigtigste redskab.
Filstier, symlinks og sikre implementeringsstrategier
OPcache er stibaseret. Derfor fokuserer jeg på implementeringsstrategien:
- Atomic Releases via Symlink (f.eks. /releases/123 -> /current): Rent, men vær opmærksom på opcache.use_cwd og realpath-adfærd. Jeg undgår dobbelte caches ved at alle arbejdere konsekvent ser den samme reelle sti.
- Med validate_timestamps=0 skal cachen overalt Tømmes: Efter skiftet flusher jeg OPcache målrettet på alle hosts/pods og ruller PHP-FPM kontrolleret igen.
- Jeg afstemmer realpath_cache_size og realpath_cache_ttl med OPcache, så filopslag forbliver hurtige og stabile.
- På netværksdrev (NFS/SMB) øger jeg file_update_protection og designer implementeringer, så filer erstattes atomart.
For meget hurtige genstarter bruger jeg ofte en totrinsprocedure: først opvarmning i baggrunden, derefter en kort, koordineret genindlæsning af alle arbejdere, så den første live-trafik allerede finder en varm cache.
Filcache, opvarmning og priming
Ud over den delte hukommelse kan OPcache bytecode valgfrit skrive til disken (opcache.file_cache). Dette er nyttigt i særlige situationer:
- I container-miljøer kan en filcache mellem Reducer FPM-genstarters re-kompilerings-tider, hvis lageret er hurtigt.
- Jeg bruger opcache.file_cache med forsigtighed: På langsomme eller distribuerede filsystemer giver det ikke meget og øger kompleksiteten.
- opcache.file_cache_only er et særligt tilfælde for miljøer uden SHM – ikke almindeligt anvendt i performance-opsætninger.
Til opvarmning laver jeg små „primere“:
- Et CLI-script kalder opcache_compile_file() for hot files, f.eks. autoloader, centrale framework-klasser, store hjælpeprogrammer.
- En crawler besøger de vigtigste ruter (hjemmeside, login, checkout), så bytecode og efterfølgende caches er varme i tide.
- Jeg planlægger opvarmningen, så den er færdig kort før versionen skifter.
OPcache i stakken: PHP-FPM, objektcache og sidecache
OPcache viser især sin styrke i kombination med PHP-FPM, en ren proceskonfiguration og ekstra cache-lag. I WordPress kombinerer jeg det med en objektcache (f.eks. Redis) og en sidecache, så databasen og rendering aflastes. Til dette formål er jeg opmærksom på Single-thread-ydeevne, fordi PHP-forespørgsler i høj grad lever af individuelle CPU-kerner. Hvis der alligevel opstår pres, fordeler jeg belastningen via PHP-FPM-Worker uden at vælge OPcache's Shared Memory for lille. Sådan bruger jeg Stak komplet, i stedet for kun at dreje på en justeringsskrue.
Hyppige fejl og hurtige kontroller
En for lille cache fører til evictions, som jeg kan se i OPcache-status eller phpinfo(). Hvis dette sker, øger jeg gradvist opcache.memory_consumption og kontrollerer effekten via hitraten. Hvis filerne ikke bliver hurtigere, sætter jeg opcache.max_accelerated_files højere end den faktiske filmængde i projektet. Ved implementeringsproblemer kontrollerer jeg validate_timestamps: Med 0 forbliver gammel bytecode aktiv, indtil jeg eksplicit tømmer cachen. Værktøjer som Doctrine kræver DocBlocks, derfor lader jeg save_comments=1 være for at Fejl ved at undgå manglende annoteringer.
Overvågning og fortolkning af OPcache
Jeg måler hitraten og stræber efter værdier tæt på 100 procent, så forespørgsler næsten altid starter fra cachen. Derudover overvåger jeg hukommelsesforbruget og antallet af evictions for at opdage flaskehalse tidligt. Med opcache_get_status() opretter jeg små dashboards eller fodrer eksisterende overvågningsløsninger. Så kan jeg straks se ændringer efter udgivelser eller plugin-opdateringer i tendensen. Med disse målinger træffer jeg velinformerede beslutninger. Beslutninger og tilpas kun det, der virkelig er nødvendigt.
Konkrete retningslinjer, der har vist sig at fungere:
- Hitrate > 99 % under normal og spidsbelastning; under dette kontrollerer jeg filfordeling og opvarmning.
- Fri SHM-andel konstant > 5–10 %; ellers skalerer jeg hukommelsen.
- Evictions over tid: Engangsudsving efter implementering er okay; kontinuerlige evictions indikerer underdimensionering eller stærk fragmentering.
- Hold øje med spildt hukommelse: Hvis den når grænsen, planlægger jeg en kontrolleret OPcache-genoprettelse (f.eks. i vedligeholdelsesvinduer).
Eksempel: WordPress-opsætning med høj trafik
Til store WordPress-websteder vælger jeg opcache.enable=1 og opcache.enable_cli=1, så CLI-Worker også kan drage fordel af det. Jeg sætter gerne Shared Memory til 384 MB eller højere, hvis der er mange plugins og et funktionsrigt tema involveret. Jeg øger opcache.interned_strings_buffer til 64 MB, fordi mange klasse- og funktionsnavne gentages i alle anmodninger. For ekstremt højtydende miljøer indstiller jeg validate_timestamps=0 og revalidate_freq=0, men tømmer cachen direkte efter hver udgivelse. Det er vigtigt at designe implementeringer, så der ikke er gamle byte-kode forbliver i omløb.
Praksis-workflow for tuning og implementeringer
Jeg arbejder i faste cyklusser: måle, ændre, kontrollere. Først sikrer jeg statusværdier som hitrate, belægning og evictions, derefter justerer jeg en parameter og måler igen. Før en release sletter jeg OPcache målrettet med deaktiverede tidsstempler, enten via PHP-FPM-genstart eller et lille script. Derefter kontrollerer jeg belastningsspidser med ægte trafik eller repræsentative benchmarks. Hvis der opstår mærkelig adfærd, kontrollerer jeg også Hukommelsesfragmentering, fordi de udnytter den anvendelige Fælles Hukommelsen svinder.
Et par ekstra rutiner, der har vist sig at fungere godt i teams:
- Versionering af parameterændringer: opcache.ini i repo, ændringer via pull request og changelog.
- Canary-Deploys: Først downloader en del af arbejdstagerne/pods nye versioner og opbygger cache, derefter rulles det ud til alle instanser.
- Nødknap: Et internt admin-endpoint med sikker adgang, der tillader opcache_reset() og målrettede opcache_invalidate()-kald – kombineret med opcache.restrict_api.
- Vurder størrelsesordenen: Som en grov tommelfingerregel beregner jeg indledningsvis 1–2 MB OPcache pr. 100–200 PHP-filer og justerer derefter på baggrund af de reelle målinger. Til WordPress med mange plugins tilføjer jeg en buffer.
Kort opsummeret
OPcache gør PHP-applikationer hurtigere ved at kompilere byte-kode i RAM. Med passende indstillinger for hukommelse, antal filer og tidsstempelstrategi opnår du konstant korte svartider. Sørg for at koordinere med PHP-FPM og andre cache-lag, så hele stakken fungerer problemfrit sammen. Overvåg hitrate, belægning og evictions, så du kan foretage målrettede justeringer. På den måde sikrer du dig en højtydende, pålidelig Platform til store belastninger og vækst.


