Optimalizace výkonu PHP aplikací: cachování a konfigurace

Optimalizace výkonu PHP aplikací: Caching a konfigurace

Proč optimalizovat výkon PHP aplikací

Výkon PHP aplikací rozhoduje o uživatelské zkušenosti, infrastrukturních nákladech i obchodních výsledcích. Moderní PHP (8.x) přináší JIT, vylepšení engine a rozsáhlý ekosystém optimalizačních nástrojů. Cílem je dosáhnout nízké latence, vysoké propustnosti a stabilního chování pod zátěží při zachování bezpečnosti a udržovatelnosti kódu.

Strategie: měřit → analyzovat → optimalizovat

  • Měření: APM nástroje (OpenTelemetry, New Relic, Datadog), metriky z php-fpm status, logy Nginx/Apache (p95/p99), obchodní KPI.
  • Profilace: profilery bezpečné pro produkční prostředí (Blackfire, Tideways), vývojářský Xdebug (mimo produkci), sampling vs. tracing.
  • Testování: zátěžové a stresové testy (k6, JMeter, Gatling, wrk), výkonnostní rozpočty v CI/CD, regresní testy.

Upgrade na moderní PHP 8.x

  • Výkon jádra: výrazná zlepšení v opcache, garbage collection a optimalizacích bytekódu.
  • JIT: u čistě CPU-bound úloh může pomoci; u typické I/O webové zátěže je jeho efekt omezený. Měřte podle konkrétní zátěže.
  • Nové funkce: typy, readonly, fibers, lepší json, optimalizované operace s array.

OPcache: základní kámen výkonu

  • Bytecode cache: eliminuje opakovanou kompilaci skriptů; snižuje latenci a vytížení CPU.
  • Doporučené nastavení (produkce):
    • opcache.enable=1, opcache.enable_cli=0 (případně 1 pro dlouho běžící CLI služby).
    • opcache.validate_timestamps=0 a řízený opcache reset při vydání nové verze (neměnné sestavení).
    • opcache.memory_consumption 256–1024 MB podle kódu, opcache.interned_strings_buffer 16–128 MB.
    • opcache.max_accelerated_files podle počtu skriptů (např. 20000–100000).
    • opcache.preload a opcache.preload_user pro přednačítání často používaných tříd/funkcí.
  • Realpath cache: realpath_cache_size 256k–4M, realpath_cache_ttl 300+ pro minimalizaci volání stat().

Composer a autoloading

  • Optimalizace autoloaderu: composer dump-autoload -o (classmap authoritative), minimalizuje diskové I/O.
  • Redukce závislostí: audit balíčků, nahrazení těžkých knihoven lehčí alternativou, odstranění nepoužívaných.
  • Mapování PSR-4 přizpůsobit struktuře; vyhnout se hlubokým stromům složek.

PHP-FPM: ladění procesního manažeru

  • Model: FPM používá pro každý požadavek worker; cílem je optimální počet workerů bez využití swapu.
  • Klíčové parametry: pm = dynamic|ondemand, pm.max_children, pm.max_requests, pm.process_idle_timeout.
  • Postup: změřit RSS jednoho workera při špičce → spočítat max_children ≈ (RAM - rezerva) / RSS.
  • Slowlog: request_slowlog_timeout a slowlog pro stacktrace blokujících volání.

Webový server a HTTP vrstva

  • Nginx + FPM: udržujte malé a rychlé fastcgi_buffers, správně nastavte fastcgi_read_timeout, bezdůvodně nenastavujte vysoké client_max_body_size.
  • Komprese: Gzip/Brotli pro textové assety; u PHP odpovědí používejte kompresi na reverzní proxy, nikoli v PHP.
  • Cache: Cache-Control, ETag, Last-Modified; u API podle idempotence a četnosti změn.
  • fastcgi_cache pro plně cachovatelné stránky (anonymní obsah), invalidace pomocí klíčů.

Databáze: nejčastější úzké hrdlo

  • Indexy: pravidelný audit pomalých dotazů, přidání kompozitních indexů podle vzorců přístupu.
  • Problém N+1: eliminovat eager/fetch joiny, dávkovat dotazy, využívat přenos dat v rámci jednoho požadavku.
  • ORM: omezit hydration, vybírat sloupce selektivně, použít cache druhé úrovně (Redis/Memcached), vyhnout se náročným transformacím v PHP.
  • Připojení: persistentní připojení v PDO používat uvážlivě; u FPM může docházet k neúčelnému držení připojení.
  • Read replicas: rozdělení čtení a zápisu, idempotence a konzistence (směrování zohledňující zpoždění).

Cache vrstvy a serializace

  • APCu: cache v rámci procesu pro výsledky výpočtů, konfiguraci a malé vyhledávací tabulky (pozor na invalidaci při nasazení).
  • Redis/Memcached: sdílená cache pro session, výsledky dotazů, fragmenty renderování; používejte TTL a jmenné prostory.
  • Serializer: igbinary nebo msgpack snižují objem dat a zatížení CPU oproti nativní serializaci.
  • HTTP cache: reverzní proxy (Varnish/Nginx) pro celé stránky, ESI pro fragmenty.

Sessions a souběh

  • Uzamykání: výchozí souborové úložiště session uzamyká požadavky; po přečtení zavolejte session_write_close().
  • Úložiště: Redis s locking a krátkým TTL; vyhněte se sdílení session napříč doménami, pokud to není nutné.

Asynchronní zpracování a škálování

  • Fronty: dlouhé operace zpracovávejte přes frontu úloh (RabbitMQ, Redis, SQS, Beanstalkd), v architektuře založené na událostech.
  • Dlouho běžící runtime: Swoole/AMPHP/ReactPHP, RoadRunner, Laravel Octane – omezuje režii FPM, vyžaduje pečlivou správu stavu.
  • Přesun zátěže: generování PDF, obrázků a exportů mimo webový worker (workers, serverless).

Optimalizace kódu a datových struktur

  • Minimální alokace: kvůli čitelnosti i výkonu upřednostňujte foreach před array_map; vyhněte se zbytečnému kopírování polí.
  • Řetězce: používejte .= s dostatečnou rezervou ve vyrovnávací paměti nebo implode; minimalizujte použití regulárních výrazů, upřednostňujte např. strpos.
  • JSON: používejte json_encode s vhodnými volbami (JSON_UNESCAPED_UNICODE, JSON_INVALID_UTF8_SUBSTITUTE), nepřenášejte nadbytečná pole.
  • Výpočty: pro velká čísla upřednostňujte ext-gmp před funkcemi bc*.
  • Kolekce: u velkých datových sad využívejte generátory (yield) a iterátory místo úplného načtení do paměti.

Šablonování a rendering

  • Cache šablon: Twig/Latte Blade – zapněte kompilaci a cache, minimalizujte dynamiku v šablonách.
  • Cache fragmentů: cachujte části stránky s invalidací založenou na klíčích (uživatel, jazyk, verze dat).

Bez I/O navíc: souborový systém a sítě

  • Minimalizace stat(): používejte absolutní cesty a realpath cache, vypněte nepotřebná omezení open_basedir, pokud výkon zpomalují.
  • HTTP klient: opakované využití TCP/TLS (pooling v Guzzle přes Curl handler), timeouty a circuit breakery.
  • Externí služby: hromadné operace, dávková API, idempotentní návrh.

Bezpečnost vs. výkon

  • Zakázat Xdebug v produkci, nastavit assert.active=0, vypnout zend.assertions > 0.
  • expose_php=0, vhodné nastavení session.cookie_secure, SameSite a HTTPOnly bez negativního dopadu na výkon.
  • Omezování rychlosti na reverzní proxy, nikoli v PHP, snižuje zatížení CPU.

Konfigurace runtime a OS

  • Huge pages pro OPcache (pokud jsou stabilní), připínání procesů k CPU pouze po otestování.
  • Disk: SSD/NVMe pro logy a dočasná data, rotace logů, žádné synchronní zápisy v rámci požadavku.
  • Kontejnerizace: kompilace závislostí při sestavení, neměnné artefakty, warmup opcache ve vstupním bodě.

Monitoring, upozornění a observabilita

  • Metriky: latence (p50/p95/p99), propustnost (RPS), míra chyb, saturace (CPU, paměť, I/O), délka fronty FPM.
  • Trasování: distribuované trasování (OpenTelemetry) přes web → PHP → DB → cache.
  • Logy: strukturované (JSON), korelace s trace-id, sampling při běžném provozu a úplné logování při incidentech.

Poznámky ke konkrétním frameworkům

  • Symfony: cache pro prod, opcache.preload, composer dump-env prod, vypnout debug bundle, HTTP cache s HttpCache nebo CDN.
  • Laravel: config:cache, route:cache, view:cache, Horizon pro fronty, Octane pro dlouho běžící runtime.
  • Nette: production mode, cache šablon Latte, výpis DI kontejneru a zahřátí opcache.
  • Doctrine: cache dotazů a výsledků, omezit režimy hydratace, explicitně vybírat sloupce pomocí SELECT.

Tabulka: rychlá orientační příručka k optimalizacím

Příznak Možná příčina Doporučený krok
Vysoké vytížení CPU, nízké RPS Chybějící OPcache, náročné šablony Zapnout OPcache, zapnout cache šablon, provést profilaci
Pomalé p95/p99 Dotazy N+1, I/O na externí API Dávkování, cache, timeouty a opakování požadavků s backoff
Fronta ve FPM Nízké max_children, vysoké RSS Navýšit RAM/optimalizovat kód, přepočítat max_children
Kolísavá latence GC, cold start, reset opcache Zahřátí po nasazení, stabilní strategie vydávání verzí
Blokující požadavky Uzamčení session, souborové I/O session_write_close(), přesunout session do Redis

Řízení vydávání verzí a spolehlivost

  • Nasazení Blue/Green a Canary s metrikami a automatickým návratem k předchozí verzi.
  • Neměnné artefakty: po nasazení žádné změny na serveru; zahřátí cache a opcache.
  • Příznaky funkcí: řízení zátěže a postupné zapínání náročných funkcí.

Kontrolní seznam: minimální základ pro produkční prostředí

  • Zapnutý a správně dimenzovaný OPcache včetně realpath cache.
  • Optimalizovaný Composer autoloader a audit závislostí.
  • Vyladěný PHP-FPM (pm.max_children, slowlog, stránka se stavovými informacemi).
  • HTTP hlavičky cache, komprese na reverzní proxy, fastcgi_cache pro anonymní obsah.
  • Indexy DB, odstraněné problémy N+1, cachování opakovaných dotazů.
  • APCu/Redis pro runtime cache a session bez uzamykání.
  • Monitoring p95/p99, APM traces a upozornění, zátěžový test v CI.

Závěr

Optimalizace výkonu PHP je kontinuální disciplína kombinující změny v architektuře, konfiguraci runtime, databázové vrstvě i kódu. Systematickým měřením, profilací a automatizovaným testováním dosáhnete stabilní latence, lepšího škálování a nižších nákladů. Moderní PHP 8.x s OPcache, pečlivě vyladěným FPM, využitím cache vrstev a promyšlenou prací s I/O poskytuje vynikající základ pro rychlé a spolehlivé webové aplikace.