+ All Categories
Home > Software > Vašek Purchart - Optimalizace Symfony na devu (2. sraz přátel Symfony v Praze)

Vašek Purchart - Optimalizace Symfony na devu (2. sraz přátel Symfony v Praze)

Date post: 15-Apr-2017
Category:
Upload: pehapkari
View: 582 times
Download: 4 times
Share this document with a friend
25
Optimalizace Symfony na devu @ VasekPurchart
Transcript

Možnosti optimalizace

• hardware• OS• další technologie• nastavení prostředí• nastavení aplikace

Optimalizovat je možné na různých úrovních, na seznamu jsou vypsané od největšího zásahu do stávajícího prostředí po nejmenší. V této prezentaci se chci zabývat především posledními dvěma body, právě díky jejich minimálnímu zásahu a tudíž větší dostupnosti a omezenému riziku dalších komplikací.

Nejnovější verze PHP

( source: http://talks.php.net/velocity15#/drupalbench )

Základní optimalizací je používání nejnovějších verzí PHP. Nové PHP postupně přinášejí zrychlení aplikací, které je prakticky „zadarmo“, největší zrychlení, co se týče real-world aplikací napsaných v Symfony nás čeká v podobě PHP 7. Zde je srovnání na základě Drupalu 8, který na Symfony běží a je tak blíže realitě než prosté syntetické benchmarky. ( source: http://talks.php.net/velocity15#/drupalbench )

(https://3v4l.org/GWVhT)

Je samozřejmě možné používat lokálně jinou verzi, než na které poběží projekt v produkci. Nebo používat jinou verzi (PHP 7 nebo HHVM) například jen pro spouštění testů. Já osobně toto nedělám, protože jsem již několikrát narazil na poměrně zákeřné bugy, které se pak projevily jen na produkci, nebo naopak. Snažím se mít tedy identickou verzi jako je na serveru.

Xdebug

Jedny z nejdramatičtějších zpomalení může způsobit zapnutá Xdebug extension. V posledních verzích například sám composer přidal varování, které se zobrazuje při každém jeho spuštění.

php -dzend_extension=xdebug.so bin/phpunit

Zkontrolujte si tedy, že je Xdebug vypnutý jak při webovém přístupu (mod_apache, PHP-FPM apod.), ale zároveň i v CLI. Doporučuji rozšíření loadovat jen pro nástoje, kde je bezprostředně potřeba (tj. např. viz výše spuštění PHPUnitu). Alternativou je připravit samostatné php.ini a to pak spouštět pomocí –c.

Xdebug on

Xdebug off

Zde je drobná ukázka toho, jak dramatický může být rozdíl v CLI aplikaci.

( http://php.net/manual/en/ini.core.php#ini.sect.performance )

Další optimalizace vycházejí především z toho, že Symfony (ale i jakákoliv jiná aplikace používající hodně knihoven) musí při běhu načíst velké množství souborů, což obsahuje i velké množství dotazů na disk, které může být velmi pomalé. Tyto dotazy se cachují, velikost a trvanlivost realpath cache ovlivňují tyto nastavení. Výchozí nastavení velikosti většinou nestačí pro standardní Symfony aplikaci, doporučuji zvýšit cca na 4096K.

S nastavením trvanlivosti realpath cache je to zrádnější, už výchozí 2 minuty můžou vytvořit velké WTF momenty (aplikace si může myslet, že je na disku něco komplet jiného než opravdu je). Nastavte tedy dle vlastního uvážení, ale doporučuji do build procesu (např. scriptu, který by měl zajistit, že je aplikace připravená ke spuštění – např. po přepnutí z větve do větve) přidat zavolání clearstatcache se zapnutým druhým parametrem, který tuto cache pročistí.

Pozor, clearstatcache je potřebné volat v procesu spuštěném v tom PHP SAPI, které cache chcete ovlivnit (tj. pravděpodobně v tom, na které koukáte přes browser).

( http://php.net/manual/en/function.clearstatcache.php )

Voláním této funkce můžete zjistit, jak je právě využívána realpath cache a může vám tedy pomoci s nalezením správné velikosti, pozor opět je potřeba volat v tom SAPI, pro které chcete velikost zjišťovat.

( http://php.net/manual/en/function.realpath-cache-size.php )

Byte Code Cache

• APC• OPcache (od 5.5)

Používání byte code cache znamená, že se všechny soubory nemusí pokaždé znovu parsovat a překládat do spustitelné podoby. Tato technologie je od PHP 5.5 v podobě OPcache dostupná ve většině distribucí přímo s PHP, není to tedy nic, co byste museli samostatně instalovat.

Optimalizace OPcache• Fine-Tune Your Opcache

Configuration to Avoid Caching Suprisesopcache.validate_timestamps=0

Výchozí nastavení Opcache je ale velmi opatrné a zdaleka nenabízí největší optimalizaci. Doporučuji si přečíst odkazovaný článek, který se sice zabývá optimalizací pro produkci, ale optimalizace pro dev je ve většine případů jednodušší.

Jedním z největších zrychlení je vypnutí kontrolování, jestli se soubory nezměnily od posledního zpracování. Jinak se opět pokládá velké množství dotazů na filesystém. Toto nastavení pak ale znamená, že musíte OPcache explicitně říci, kdy má zapamatované zdrojáky zapomenout (přidání do build procesu).

( http://php.net/manual/en/function.realpath-cache-size.php )

Composer autoload

• Classmap

autoritativní

composer dump-autoload --optimizecomposer install --optimize-autoloader

composer dump-autoload --classmap-authoritativecomposer install --classmap-authoritative

Dalším místem, kde je potřeba velké množství čtení z disku je samostný autoloading souborů, pokud máte hodně knihoven, které používají autoloading pomocí PSR 0 nebo 4, tak se soubory musí po jednom hledat na disku (i v několika možných lokacích).

Nemusíte spoléhat na autory balíčků a můžete si vygenerovat do classmapy všechny třídy, takže jejich poloha pak bude předem známá. Na devu není moc praktický autoritativní režim, protože to znamená po přidání každé třídy přegenerovat classmap.

Vyházet zbytečnosti

Většina Symfony projektů, které jsem viděl začíná se Standard Edition, která obsahuje „komfortní nastavení“ tak, aby nováčci nemuseli nic moc řešit a start projektu byl usnadněn. Reálně obsahuje spoustu částí, které nikdy nepoužíváte a které při každém běhu můžou zpomalovat aplikaci.

SensioFrameworkExtraBundle

Skoro všichni tak například používají SensioFrameworkExtraBundle, která nabízí hlavně výše vypsané anotace. Většina projektů, ale nepoužívá všechny tyto anotace.

SensioFrameworkExtraBundle

Přitom veěkerá funkcionalita s tímto spojená je defaultně zapnutá (aby to každý mohl bez nastavování používat).

Toto je jen jeden příklad za všechny, měli byste znát konfiguraci bundlů, které používáte.

Zbytečné listenery

• seznam aktuálně zaregistrovaných listenerů pro dané prostředíapp/console debug:event-dispatcher

Kvůli tomu, jak fungují bundly (každý si může registrovat svoje listenery, bez nutnosti vašeho nastavování) bývají právě ony zdrojem velkého překvapení. Například Standard Edition má v defaultním stavu (v době vytváření prezentace) zaregistrováno pro request 33 listenerů.

To, které listenery jsou pro dané prostředí registrované můžete zjistit pomocí konzole a postupně dohledat, jak deaktivovat ty, které nepotřebujete.

Další adepti

• formuláře• mailer• ? profiler• ? logování• ...

• kontrolujteapp/console debug:config

Další oblasti defaultní konfigurace, které je možné podle zaměření projektu vypnout. Pokud nepoužíváte profilování a logování na devu pořád a přitom např. kvůli produkci logujete hodně věcí, můžete tyto nastavení zapínat jen pro samotný debugging, když se něco pokazí.

• vs

Konfiguraci je ale potřeba ověřovat, protože některé její části můžou být navzájem provázané, takže i když dokumentace tvrdí, že formuláře jsou defaultně vypnuté a aplikace je v konfiguraci explicitně nezapíná, tak reálně jsou ve Standard Edition zapnuté.

Jakákoli optimalizace na devu je vždycky o balancování mezi pohodlím a rychlostí. Na devu, tím, že měníme kód, tak očekáváme, že jakmile aplikaci spustíme, tak se bude chovat přesně podle posledních úprav. Jediné, jak se na to ale spolehnout je vykonat vše od začátku jen na základě aktuálních zdrojáků. Nebo zkontrolovat, že se od minule nic nezměnilo a jde použít staré „výsledky“ některých operací. Oba tyto úkony jsou ale velmi náročné a tak většina optimalizací pracuje s tím, že musíme sytému pomoci v tom, aby věděl, kdy (ne)může staré výsledky použít.

Assetic

app/console assetic:dumpapp/console assetic:watch

Assetic například ve výchozím nastavení generuje všechny soubory dynamicky pro každé spuštění, což je velmi pomalé. Tuto funkcionalitu lze vypnout, je pak ale právě potřeba zajistit volání generování po změně patřičných souborů. To dělat buď manuálně (a jako součást build procesu). Je to ale celkem nepohodlné pro průběžný vývoj, kde na to nechceme myslet. Je možné tedy kontrolovat soubory, o kterých víme, že ovlivňují výsledek automaticky a generování spustit jen pokud se změní. (Watch v asseticu je prý zabugovaný, používám toto jen jako příklad přístupu, viz dále).

Doctrine

• disablování lazy generování proxy tříd

• vygenerování

parameters: doctrine.orm.auto_generate_proxy_classes: false

app/console cache:warmup

Podobný princip jako je ukázán na minulém slidu je možné aplikovat i u dalších částí – většinou bez přímé podpory autorů. Tady je ukázka jak podobný proces – generování proxy tříd pro Doctrine entity přesunout z lazy evaluace při každém requestu do watch procesu. Prvně je nutné zakázat lazy generování, což zároveň odemkne možnost pomocí cache:warmup vygenerovat všechy proxy najednou. Pak ale musíme zařídit tech watch...?

JS to the rescue!

Je zbytečné si něco takového programovat v PHP, většina projektů tak jako tak používá nějaký frontend buildovací nástoj, například Grunt, Gulp, Webpack a další. Myslím že všechny tyto nástroje mají prostředky jak watchovat změny, protože live reload je ve světě JS aktuálně celkem standardem. Je pak jen otázkou konfigurace, jak toto propojit s tím, co potřebujeme.

Ve zdejší ukázce jsem zvolil Grunt jen proto, že jsem ho na podobnou funkcionalitu už použil.

Repozitář dema

Prohlédněte si příklad na Symfony Demo aplikaci, kde po následování základní instalace npm modulů, můžete watch spustit a po úpravě jakékoliv entity dojde automaticky k vygenerování všech proxy tříd.

S trochou dalšího programování by bylo možné přegenerovávat jen změněné entity, ale tímto chci především ukázat, jak snadné je začít aplikovat tento přístup k optimalizaci na devu.


Recommended