fbpx
Damir Špoljarič

Docker v poslední době nabývá na popularitě. O Dockeru můžeme mluvit jako o kontejnerové virtualizaci, což je správně, ale určitě to plně nevystihuje jeho účel. Možná je přesnější hovořit o izolaci procesů. Ani to ale nevyjádří přesnou podstatu.

O Dockeru lze uvažovat i jako o virtualizaci, která nemá žádný overhead. Start kontejneru je okamžitý, kernel se sdílí s podkladovým OS a ani nedochází k žádnému zpomalení při vlastním běhu programu, resp. jde vlastně o fork systemd procesu. Nejlepší tedy bude mluvit o Dockeru jako o Dockeru.

Výhody používání Docker

Docker, stejně jako jiné kontejnerové virtualizace, odstraňuje jeden z velkých problémů samotné virtualizace – nároky na hardware. Některé virtualizace mohou spotřebovat až 1/5 výkonu. Klasická virtualizace, jak ji zná dnes asi už každý, pracuje s modelem hardware – hostitelský OS – hypervisor – klientský OS – aplikace.

U Dockeru je to jinak. Kontejnery totiž sdílí jednu linuxovou instanci, nad kterou se pak jednotlivé izolované procesy spouští. Pracuje tedy s modelem hardware – OS – docker engine – a pak už rovnou aplikace.

Technologie Docker není náhradou za LXC. „LXC“ se odkazuje na jádro Linuxu (jmenovitě jmenných prostorů a řídících skupin), které umožňuje navzájem vytvářet procesy mezi jednotlivými oblastmi a řídit přidělování prostředků. Na vrcholu této nízké úrovně funkcí jádra nabízí Docker nástroj na vysoké úrovni s mnoha výkonnými funkcemi.

Docker je (narozdíl od strojů) optimalizován pro nasazení aplikací. To se odráží v jeho rozhraní API, uživatelském rozhraní, filozofii návrhu a dokumentaci. Naproti tomu skripty LXC se zaměřují na kontejnery jako lehké stroje – v podstatě na servery, které se bootují rychleji a potřebují méně paměti.

Nejzajímavějši funkce Docker

Přenosné nasazení mezi stroji

Docker definuje formát pro zabalení aplikace a všech jejích závislostí do jednoho objektu nazvaného kontejner. Docker jako kontejner lze v přeneseném smyslu slova skutečně s kontejnerem srovnávat. Cokoliv, myšleno aplikace a její prostředí, do něj uzavřete, můžete snadno přenést kamkoliv. Kdekoliv ho použijete bude fungovat stále stejně.

Automatický build

Docker obsahuje nástroj pro vývojáře k automatickému sestavení kontejneru ze zdrojového kódu s plnou kontrolou závislostí aplikací, vytvářením nástrojů, balením, apod. Volně jsou k použití make, maven, chef, puppet, salt, balíčky Debian, RPM, zdroj tarballs nebo jakékoli kombinace výše uvedených, bez ohledu na konfiguraci strojů.

Verze

Docker obsahuje funkce typu git pro sledování následných verzí kontejneru, kontrolu rozdílu mezi verzemi, zavádění nových verzí, rollback atd. Historie také zahrnuje, jak byl kontejner sestaven a kým. Získáte tak sledovatelnost celé cesty z produkčního serveru až k vývojáři. Docker také provádí inkrementální nahrávání a stahování, podobně jako git pull, takže nové verze kontejneru mohou být přenášeny pouze odesláním diffs.

Klony

Každý kontejner může být použit jako “rodičovský obraz” pro vytvoření více specializovaných komponent. To lze provést ručně nebo jako součást automatizovaného buildu. 

I když ve způsobu používání Dockeru nikomu nic nebrání, měly by se v rámci udržitelnosti vytvářet pouze kontejnery obsahující jednu aplikaci. Pokud použijete aplikací více, vzniká riziko konfliktních závislostí, a to jde přímo proti filosofii Dockeru, kterou je snadná přenositelnost. Proto jsou od více-aplikačních kontejnerů vývojáři samotným Dockerem odrazováni.

Při definování docker image je především nutné dodržet alespoň tato pravidla:

  • mít explicitně deklarované a izolované závislosti
  • konfiguraci mít uloženou do prostředí
  • počítat s možností neomezeného škálování aplikace nahoru i dolů

Bezstavové vs. stavové aplikace

Obecně se pak dá říct, že je Docker nejsilnější v provozu bezstavových aplikací. U aplikací stavových, jako jsou typicky databázové servery, dává jeho použití smysl pouze v určitých případech. U jednoinstančních instalací Dockeru může být smysl v provozování stavových aplikací pouze pro účely nějakých development nebo testing verzí.

Pokud se ale budeme bavit o provozování Dockeru na nějaké větší platformě s množstvím fyzických serverů, tak mohou být škálovatelné stavové aplikace zajímavou možností, jak v závislosti na vytížení aplikace upravovat její výkon. Typicky Docker Mysql Cluster.

Na závěr lze říci, že se jedná o velmi sofistikovaný a výkonný nástroj pro development a testing aplikací. Pro jeho použití v produkčním prostředí je ale nutné projít trošku delší cestu.

Pokud hledáte prostředí pro větší projekty, které je postavené na Dockeru, mrkněte na naší službu Managed Platform for Kubernetes. Ta nabízí plně automatizovanou infrastrukturu pro Docker aplikace.


Damir Špoljarič

Magento je výkonná e-commerce platforma, která zahrnuje vše, co je třeba pro prodej online. Kromě samotného e-shopu dokáže řešit i sklad, marketing, fakturace a účetnictví. V současné době Magento přichází ve dvou verzích: Magento Open Source (dříve Magento Community Edition) a Magento Commerce (který je určen pro vetší společnosti s vlastními vývojáři).

Magento je jednou z nejvíce využívaných e-commerce platforem a v hodnocení uživatelů získává konzistentně vysoké hodnocení. Ke správnému fungování Magenta je nicméně třeba mít zkušeného vývojáře samotné aplikace a také zkušeného poskytovatele hostingu, který ví, jak servery pro Magento optimalizovat.

Potřeba výkonného hostingu

Jak jsme již zmínili, u Magenta nelze podcenit hosting. Platforma je náročná na výkon a tomu musí odpovídat i parametry hostingu. Pokud se oprostíme od problémů a chyb samotné aplikace, tak je většina problémů v Magento způsobena malým výkonem webového serveru, resp. prostředím, kde je Magento provozováno. Magento je pomalejší a má mnohem více requestů než ostatní systémy, ale existuje několik způsobů jak platformu urychlit.

Zrychlení Magenta

Magento obvykle nelze provozovat přímo na webovém serveru, ale je nutné využívat cachovací proxy (aktuálně je podporovaný pouze Varnish).
Pokud chcete, a v dnešní době je to už standard, provozovat SSL verzi, je nutné před Varnish proxy předsadit Nginx nebo jiný SSL terminátor. Co se týká samotného webového serveru, je možné použít Apache s PHP modulem nebo Nginx s PHP-FPM. Jedním z nejúčinnějších způsobů, jak dál urychlit Magento, je použití akcelerátorů PHP. U základních instalací je APC prohlašována za nejlepší řešení.

Možná jsou tedy dvě řešení:

  • NGINX → VARNISH → APACHE (PHP-MODUL + APC, Memcache, Redis) → MariaDB
  • NGINX → VARNISH → NGINX (PHP-FPM + APC, Memcache, Redis) → MariaDB

V případě větších instalací je pak vhodné využívat Redis pro cache i jako session handler.
Pokud se rozhodnete provozovat celou instalaci na jednom serveru, je nutné mít výkonný hardware nebo hosting, který Magento přímo podporuje. O paměť, CPU a IOPS budou soupeřit hlavně PHP, MySQL a Varnish.

Provoz Magenta v clusteru

Pokud se rozhodnete provozovat Magento v nějakém clusterovém režimu (buď kvůli výkonu nebo kvůli vysoké dostupnosti), Magento s tímto nastavením nativně nepočítá. Existuje několik možností, jak cluster sestavit:

  • Složitější varianta je používat za load balancerem Varnish na každém backendu, ale pak je nutné se správně vypořádat s disvalidací cache a s podobnými dalšími problémy.
  • Jednodušší způsob je nechat balancing na Varnish cache, která je sama o sobě dostatečně výkonná, aby dokázala zvládnout předávat požadavky na mnoho backendů.

Při clusterových instalacích se zároveň doporučuje počítat s dedikovaným serverem pro admin backend, u kterého paradoxně cachovaní není úplně žádoucí. U verzí 2 a méně se doporučuje povolit funkci Magento Compilation pro urychlení úložiště Magento.

Z naší zkušenosti vyplývá, že nejčastěji dochází ke zpomalování vlivem následujících chyb v aplikaci:

44 % SQL dotazů uvnitř smyčky
25 % načítání stejného modelu několikrát
14 % využití redundantního datového souboru
10 % výpočet velikosti pole na každé iteraci smyčky
7 % neefektivní využití paměti

Závěr: Zkušený hosting a zkušený programátor vyladí fungování Magenta

Mezi výhody Magenta patří robustnost a to, že je univerzální. Na druhou stranu je těžké zajistit, aby fungovalo optimálně. Pokud uvažujete o využití Magenta pro váš e-shop, ujistěte se, že:

  1. programátor aplikace má s Magentem zkušenosti,
  2. hosting, který jste si vybrali ví, jak server pro Magento vyladit tak, aby vše perfektně fungovalo a neztrácela se rychlost.

Damir Špoljarič

Scaling je často skloňované slovo a zaklínadlo všech moderních online apps jako must have. Byť je často škálování považováno za výhradní atribut infrastruktury, pravdou je, že škálování ovlivňuje zejména aplikace a její technologické požadavky. Vysvětlíme si, čemu byste se měli jako vývojáři moderních aplikací pokusit vyhnout, aby byla zajištěna maximální možnost škálování.

Scaling, Autoscaling, Scale-up, Scale-out

Na začátek krátké vysvětlení základních pojmů. Škálování, tedy scaling, je navyšování výpočetních prostředků aplikací nebo paralelizace výpočetních jednotek (v zásadě stále „přidávání výkonu“). Pokud se má škálování odehrávat dynamicky a automaticky dle aktuální potřeby, jde o autoscaling. Autoscaling se rozhoduje podle různých metodik – load serveru, objem datových toků, počet requestů, latence requestu, množství chyb, které vrací aplikace z důvodu nemožnosti request odbavit.

V Zeropsu budeme u autoscaling podporovat téměř vše zde uvedené. Oproti AWS a jiným obdobným tradičním cloudovým službám však nebudeme uživatele trápit laděním metrik a Zerops provede nastavení podle best practices pro daný use case, zkrátka Zero Operations ;-).

škálování: scale up vs. scale out

Scale-up je model vertikálního škálování, což je nejtypičtější způsob škálování, na který aplikace nemusí být nijak zvlášť připravená. V zásadě jde o navyšování výkonu serveru. Tento model má tu nevýhodu, že často nejde provádět za běhu, jeho možnosti nejsou neomezené a je také možné, že některé aplikace již nedokáží takový výkon v rámci jednoho serveru utilizovat a bottleneck je poté někde „uvnitř“ aplikace.

Scale-out je škálování formou paralelizace výpočetních jednotek – přidávání serverů, virtuálních serverů, kontejnerů za load balancerem. Na tento způsob škálování musí být aplikace připravena, výhodou oproti tomu je větší rozsah možností škálování.

Scaling killer 1 – relační databáze

Nejtypičtějším zabijákem škálování jsou relační databáze (MySQL, PostgreSQL, …), což jsou produkty, které vznikly před více než 20 lety v době, kdy pojem škálování v tomto pojetí prakticky neexistoval. Podpora pro clusterování byla různě dolepována až následně, popř. řešena jinými produkty třetích stran. Nejdříve je tedy potřeba se zamyslet, zda vůbec relační databázi ve vaší aplikaci potřebujete používat.

Například e-shopy s objednávkami, fakturami, uživateli apod., vyžadující ukládání dat do něčeho, co splňuje vlastnosti ACID, se bez relační databáze neobejdou. Zamyslete se nad tím, zda není možné v případě vašeho use case použít některou z noSQL databází, které byly většinou už od začátku koncipovány jako clusterovatelné, tedy škálovatelné.

Stále se ještě setkávám s tím, že někdo do relační databáze ukládá logy, sessions a další, což jsou všechno věci, na které existují specializované nástroje (pro sessions například in-memory noSQL databáze redis, logy např. syslog apod.). Naprosto nejhorší z pohledu škálování a relačních databází jsou zápisové operace, kde je reálná možnost škálování pouze vertikálně.

U selectů je ještě možné provoz rozdělit. Například Amazon RDS umožňuje přidávat read-only replicy, Zerops bude podporovat Galera cluster jako službu a bude zajišťovat výrazně větší pohodlí z pohledu škálování. Nicméně princip nemožnosti škálovat zápisové operace horizontálně platí v obou případech. Měli byste se tak vyhnout například využívání relační databáze k ukládání různých statistik, číselných řad a dalších (přesně k tomuto účelu se hodí více noSQL databáze – mongo, ElasticSearch apod.).

Relační databázi z pohledu horizontálního škálování je třeba brát jako nutné zlo a operace, zejména zápisové, je potřeba maximálně omezit z pohledu náročnosti a intenzity.

Scaling killer 2 – sdílený filesystém

Moderní aplikace se bez sdíleného filesystému již obejdou, drtivá většina aplikací však stále ne. Aplikace předpokládá, že má v adresářové struktuře uloženy kromě aplikace i data – tedy obrázky, logy atd. Špatně napsané aplikace ukládají do adresářové struktury různé cache. Filesystém je další desítky let starou záležitostí, která již měla dávno zhynout.

Pokud se nebavíme o aplikaci globálního rozsahu a nepracuje se s filesystémem nekoncepčně, nejde zas o takový problém, protože se na limity pravděpodobně nemusí nikdy narazit. Pokud se ale s FS pracuje nekoncepčně, hrozí zásadní problém, který žádné škálování ničeho většinou nevyřeší, navíc jde často o problémy, které o sobě nedají vědět dříve, než se reálně projeví.

Typicky jde o :

  • špatnou adresářovou strukturu – ukládání statisíců (nebo mnohem více) objektů (souborů, adresářů) v jednom adresáři. Otevření takového adresáře pak mnohdy trvá spoustu minut.
  • velké množství operací s filesystémem – zbytečné operace při každém přístupu uživatele nad mnoha soubory a generování lstat operací (typicky jsou to funkce v PHPku na ověření existence obrázku při každém přístupu apod. nebo absence souborové cache, kdy aplikace při každém přístupu generuje přístup na filesystém)
  • ukládání cache do adresářové struktury – pokud ukládání do adresářové struktury, tak určitě ne do sdíleného filesystému mezi více servery, ale do ramdisku na lokálním serveru. Na sdíleném filesystému krok přetížení hrozí čekáním na soubor cache vlivem zámku souboru, který zrovna vytvořil jiný server, který s cache pracuje.
shared filesystem / sdílený filesystém

Jak si poradit bez sdíleného filesystému? Je nutné dodržovat základní filosofii rozdělení aplikace a dat. Aplikace by měla být provozuschopná i v read-only režimu (poté může běžet klidně v ramce) a neměla by vytvářet žádné lokální soubory (případný temp adresář pro dočasná nedůležitá data se řeší jako jeden zapisovatelný adresář umístění také na ramdisku). S daty se pracuje tak, že se použijí nástroje, které jsou k tomu určené – například syslog pro vzdálené logování, object storage pro práci s obrázky a dalšími uživatelskými daty, no a samozřejmě databáze.

Výše uvedení zabijáci škálování jsou nejčastější příčinou zhoršených možností škálování infrastruktury, se kterými se 11 let setkáváme u velkých internetových projektů.


Damir Špoljarič

Řada velkých projektů, které využívají MySQL/MariaDB se již setkala s tím, že jim jednoduše nestačí provozovat jeden server či “hloupou” asynchronní master-slave repliku a že pro nutnost pohodlného horizontálního škálování musí připravit svoji aplikaci pro provoz databáze v MariaDB galera clusteru. To bohužel přináší poměrně zásadní předělání architektury aplikace, aby se vše přizpůsobilo vlastnostem clusteru, eliminovalo se riziko vzniku dead-locků a jiných komplikací.

vshosting~, jakožto největší Managed Services provider ve Střední Evropě, má s provozem náročných databázových clusterů mnoho zkušeností. Provozujeme v managed režimu na Galera clusteru například Shoptet, což je platformě pro více než 10.000 eshopů.

Pro zjednodušení části komplikací s přechodem do clusteru existuje nástroj zvaný MaxScale, na který se dnes podíváme.

Využití MaxScale při přechodu ze single node MySQL na MariaDB (Galera) cluster

Při přechodu z jednoinstanční mysql na cluster je obvykle nutné provádět aplikační změny, protože bězné balancování provozu přes tcp toho mnoho neumožňuje. Při takovém typu nasazení se pak obvykle stává, že se provádí transakční zápisové operace na více nodech nebo se čtou data z nodů, kam se ještě nestačila synchronizovat.

Potom je nutné vytvářet různé připojovací konektory do clusteru podle typu prováděné operace, případně upravit vlastnosti clusteru tak, aby na sebe nody vzájemně čekaly. To pak výkon clusteru snižuje. Při nasazení MaxScale se sloučí výhody tcp balancingu s přidanou logikou. Nejsou tedy nutné úpravy aplikace a provoz se směruje na jeden db konektor.

Pokud je cílem maximálně využít cluster, co se týká výpočetní kapacity a nenechat ho jen ve stavu vysoké dostupnosti, je možné vytvořit několik db konektorů podle typu použití např. Readonly pro rychlé čtení informací, readwritesplit pro automatické směrování zápisových operací a query caching pro dotazy, které se často opakují. To všechno pro dosažení maximálního výkonu clusteru.

Základní popis MariaDB MaxScale

MariaDB MaxScale je databázový proxy server, který rozšiřuje vysokou dostupnost, škálovatelnost a bezpečnost serveru MariaDB a současně zjednodušuje vývoj aplikací tím, že jej oddělí od základní databázové infrastruktury.

Zjednodušeně řečeno je to databázová proxy, která předává query do databáze na jeden nebo více databázových serverů.

MaxScale je navržen s rozšiřitelnou architekturou, která podporuje pluginy a rozšiřuje svou funkci nad transparentní vyvažování zátěže, aby se stala například databázovým firewallem. S vestavěnými pluginy pro více směrovačů, filtrů a protokolů může být služba MaxScale konfigurována tak, aby předala žádosti o databázi a upravovala odezvy databáze na základě předem definovaných požadavků – například k maskování citlivých dat apod.

Přesměrování se provádí pomocí pravidel, založených na sémantickém pochopení databázových query a rolích serverů v rámci clusteru databází.

MaxScale využívá rozsáhlé možnosti asynchronního I/O operačního systému Linux v kombinaci s pevným počtem pracovních podprocesů. Epoll se používá k zajištění události řízeného rámce pro vstup a výstup přes sockety.

Služby poskytované MaxScale jsou implementovány jako externí, sdílené, objektové moduly načítané za běhu. Běžně používané typy modulů jsou protokol, směrovač a filtr. Modul protokolu zajištuje komunikaci mezi klienty a MaxScale a zároven mezi MaxScale a backendy. Směrovač kontroluje dotazy od klientů a rozhoduje o cílovém backendu. Rozhodnutí jsou obvykle založena na pravidlech směrování a na stavu backendů. Filtry poté pracují s daty, které přes MaxScale procházejí.

Základní funkce

Firewall

MaxScale obsahuje filtr brány firewall pro blokování dotazů na základě pravidel nakonfigurovaných například na základě typu příkazu, použitých funkcí, vybraných sloupců nebo frekvence dotazů. MariaDB MaxScale 2.1 rozšiřuje filtrování na připravené příkazy.

Denial of service protection

MaxScale používá plugin omezující sadu výsledků query, aby se zabránilo dotazům, předpřipraveným příkazům a uloženým procedurám způsobit výpadek služby, vrácením příliš velkého množství dat. Maximální velikost sady výsledků query lze nakonfigurovat v řádcích nebo bajtech.

Read-Write Split

MaxScale obsahuje směrovač, který rozděluje čtení a zápis, když je sql server nakonfigurován jako multi-master (galera cluster) nebo master/slave (replika). Zápisy jsou poté prováděny jediným hlavním uzlem a čtení jsou prováděna na všech slavech – a to lze provést bez úpravy aplikace.

Change-data-capture

MariaDB MaxScale obsahuje protokol pro změnu dat, který v kombinaci s routerem Avro čte události binárního logu a přenáší je do klientů, kde mohou být data interpretována jako objekty Avro nebo JSON dokumenty.

Data masking

MaxScale používá filtr na maskování dat, který chrání citlivá data kontrolou výsledků dotazu a zmatením dat v určitých sloupcích na základě nakonfigurovaných pravidel. Při kombinaci s filtrem brány firewall databáze lze omezit přístup k citlivým datům.

Bulk insert streaming

MaxScale používá filtr pro hromadné vkládání insertů a přeměňuje všechny inserty v rámci explicitní transakce na jeden datový tok CSV pro přímé načítání s větší účinností, zlepšení výkonu a snížení síťového provozu.

Schema-based sharding

MaxScale obsahuje směrovač schémat pro podporu vícenásobného prostředí, kde každé spojení má vlastní schéma a schémata mohou být v různých databázích nebo vytvořit jednotnou logickou databázi z více fyzických databází – vše transparentní pro aplikaci.

Query caching

MaxScale používá filtr pro ukládání dotazů do mezipaměti, který zlepšuje výkon opakovaných dotazů a zároveň snižuje pracovní zatížení na podkladové databázi v závislosti na nastavených pravidlech – doba trvání, maximální počet řádků / velikost souborů, maximální počet záznamů apod.

Známá omezení / limity

Syntaktický analyzátor MaxScale správně analyzuje příkazy WITH, ale nedokáže shromáždit sloupce, funkce a tabulky používané v SELECTu definující klauzuli WITH.
V důsledku toho databázový firewall neblokuje příkazy WITH, kde SELECT klauzule WITH odkazuje na zakázané sloupce.

Transakce XA nejsou zjištěny jako transakce MaxScale. To znamená, že všechny příkazy XA budou považovány za neznámé příkazy a budou považovány za operace, které potenciálně změní databázi (v případě readwritesplit jsou příkazy směrovány do masteru).

MaxScale nebude sledovat stav transakce XA, což znamená, že všechny dotazy SELECT prováděné uvnitř transakce XA mohou být směrovány na servery, které nejsou součástí transakce XA.
Tomuto omezení lze na straně klienta zabránit vypnutím automatického vypnutí před provedením všech transakcí XA.

U filtrů není zaručeno, že obdrží kompletní pakety MySQL, pokud jsou použity s readconnroute směrovačem. To lze opravit pouze pomocí směrovače readwritesplit.

ReadWriteSplit

Čtení dotazů je směrováno na hlavní server I v následujících situacích:

* dotaz je spuštěn uvnitř otevřené transakce
* dotaz je připravené prohlášení
* příkaz obsahuje uloženou proceduru nebo volání UDF
* pokud je uvnitř jednoho dotazu několik příkazů.

Věříme, že se vám náš dnešní článek líbil a chystáme pro vás řadu dalších odborných zajímavostí ;-).


vshosting~

FTP není cesta

Když chce náš zadavatel vidět ukázku hotové práce, či tester brečí, že nemá co testovat, není nic jednoduššího než prostě otevřít to FTP, překopírovat data na webhosting a hotovo. Tester nám to otestuje, zjistí, že jsou tam chyby (ještě aby nebyly), my je opravíme a znovu vypublikujeme.

Vše super až do okamžiku, než tam pošleme tak rozbitou aplikaci, že prostě neběží vůbec a my okamžitě musíme vrátit tu minulou verzi. No jo, ale na jaké verzi to minule běželo? Pamatuje si to někdo z vás? Copak z FTP zjistím, jaká tam byla verze? Ooops.

Git na server nepatří

Ok, tak FTP cestou jsme se ještě zatím nevydali, rovnou jsme šli na “level 2”. Na server vlezu přes SSH, projekt nainicializuji pomocí git clone a všechny updaty projektu jsou pak jen “git pull”. Když je třeba něco víc, tak to zaobalím shell scriptem, který to “všechno udělá”. Stáhne novou verzi z gitu, aktualizuje composer, promaže cache a jede se.

Celý deploy je pak jen SSH na server a spustit /projekt/deploy.sh. Prostě úžasně jednoduché a snadné. Ale má to tři zásadní nevýhody. Jednak pokud každá aplikace běží na jiném serveru, pořád jen lovíte to správné SSH a vzpomínáte, kam máte vlastně jít a co dělat. Tak ty data zapíšeme do wiki a problém solved ?

…až do doby, co ten jediný v týmu, který doteď měl odvahu na to, aby na serveru na ostré pouštěl ty scripty, o kterých nikdo neví, co udělají, a modlil se u toho, že to dopadne a aplikace pak ještě poběží, třeba onemocní a není nikdo jiný, kdo by to uměl udělal. No a tester stojí a kouká do stropu, protože nemá co dělat. Ale tak jo, zaškolíme dalšího. Přemluvíme toho windowsáka, co si myslí o linuxu, že je to nadávka, vše mu pečlivě vysvětlíme a naučíme, aby, až zase dostaneme rýmičku, byly projekty jako v bavlnce.

Takhle to docela funguje, až na to, že ty deploye jsou otravná věc a zdržuje to. Několikrát denně na server, aktualizovat projekt, vrátit se k práci, aby za hodinu zase…? Prostě jak “u blbečků na dvorečku”. Nešlo by to, aby se to na ty servery dostalo nějak samo? Proč by programátor, měl aplikaci deployovat? To přeci není naše práce, nás to zdržuje a otravuje. Ale zase ono to přece funguje, tak to tak necháme.

Společná řeč s adminem

Takhle se vesele jede do doby, než přijde rána z čistého nebe. Přijdou za vámi admini a oznámí, že SSH na produkční server na projekt XYZ dát nemohou z bezpečnostních důvodů. Proč by taky měl mít programátor přistup k produkci. Jednak se potom neustále dohadujete, kdo aplikaci rozbil, zda špatný deploy, nebo admini jejich aktualizacemi. Kromě toho taky nechceme, aby programátoři měli přístup k ostré databázi a jiným službám.

Po několika týdnech dohadů ty přístupy stejně nedostanete a všechna jistota je pryč. Prý jim máme dávat aplikace v podobě deb balíčku a oni si to nainstalují sami. PHP jako deb balíček? To myslí vážně? Oni ti admini asi v životě neviděli webovou aplikaci. Kdo to kdy slyšel, aby se webové aplikace publikovaly jako deb? A jak asi udělám nějaký balíček? …..

Po vystřízlivění a zjištění, že fakt není jiná možnost, nakonec zjistíme, že vytvořit deb balíček jde plně automatizovaně. Takét to má tu výhodu, že vím přesně, na jaké verzi aplikace jedu a pokud potřebuji “rollback”, jen udělám downgrade balíčku.

Plná automatizace je správná cesta

Přešli jsme tedy na “level 3”. Po push do repozitáře se spustí v GitLab-CI, které stáhne závislosti z composeru, spustí testy, sestaví deb balíček a pošle ho do apt-repository a dle git-branch rovnou ten balíček ihned na serveru nasadí (pokud má SSH [test či devel]).

Deploy u nás tedy probíhá tak, že prostě pošleme svůj kód do gitu, provedeme code-review a následně si mergneme větev do testu (develu dle libosti). V ten okamžik má test/devel verze ihned novou verzi a “křeček tester zase může testovat jak divej” a nás to nezdržuje v práci. No a až je aplikace hotová a je třeba ji nasadit na produkci, jen napíšeme, ať admini nainstalují verzi balíčku x.y.z a dál se o to nestaráme.

Jak jsme mohli žít bez automatického deploye pomocí deb balíčků?

Vývojový tým vshosting~


vshosting~

Jsme tu všichni hrdě odkojení nettisté. A pak to přišlo, vesmír se sesypal jak domeček z grafických karet, do kanceláře vtrhne náš šéf, tedy (z logiky věci) ten nejmoudřejší, a zařve: “Co když Davida Grudla přejede tatrovka? A to je dost pravděpodobný… Co s náma proboha bude? S přejetým Nette to nikdy nespíchnette…”

A tím to začalo…

Nový PHP framework

Volba nového PHP frameworku padla jednomyslně na Symfony. Pečeme u nás aplikace jak pro vshosting~ (čímž jsou ty internety zas o něco lepší), tak pro jeho klienty. Jedna z nadcházejících výzev je chystané REST API pro nový ticketovací systém. A na to je třeba mít kudly pořádně nabroušené a výpeky božsky redukované.

Jen pro představu, jaká nálož bude v pekáči: verzování s maximálním znovupoužitím již napsaného (zbytečné psaní je zbytečné) a kompatibilitou dopředu, dozadu i nahoru a dolů, strojové generování dokumentace pomocí Swaggera (bývá zvykem, že hlavní a jediná dokumentace se nachází za nefunkčním odkazem, ale není to úplně ono), použití Elasticu (megaúložiště, do nějž se replikuje databáze, aby čtení dat včetně fulltextového vyhledávání v milionech záznamů bylo v řádech desítek milisekund, tedy nechutně rychlé), automatizovaná validace vstupů (důvěřujeme, ale prověřujeme) včetně hlášení všech chyb najednou (čtenář se nesmí napínat, aby nedostal infarkt), automatizovaná validace výstupů (nevěříme ani sami sobě), autonaplnění výstupního objektu daty z Elasticu atd. atd. atd.

Pečeme REST API

Symfony pomůže v mnohém. Grunt nám dá FOSRestBundle, který zajistí základní routování (včetně typu requestu – GET, POST, PUT ad.) dle názvu metody v controlleru a naplnění vstupního objektu příchozími daty.

Pokud použijeme základní symfonní JSON response, můžeme z ní trochou ladných pohybů vykouzlit jak success API response (která přijme výstupní DTO objekt, zvaliduje a šup s ním ven jako JSON), tak error API response (která přijímá všechny API exceptions a z nich automaticky sestaví JSON odpověď včetně HTTP statusu, kódu chyby, chybové hlášky a případně dalších doplňujících dat). Pokud jsme líní a nechceme dokola psát error response do každé metody každého controlleru (a do většiny metod vícekrát), navěsíme na událost typu EXCEPTION listener, v němž danou chybu zpracujeme, a v controllerech pak stačí sázet API výjimky jak jahody do koláče.

S validacemi vstupu nebo výstupu pomůže symfonní validátor, který pomocí jednoduchých anotací zvládá i hutnější validace, nejen obvyklý basic jako datový typ, čas, email… ale také rozsah, porovnávání, IBAN ? a další. Pro vyšší výkon lze samozřejmě validace zamrazit do keše a schovat na příští sezónu. Validaci vstupu stačí provést v rámci requestu FOSRestBundle, a pokud to chceme ještě potunit a nebaví nás sbírat $validationErrors v každé metodě každého controlleru, stačí na request navěsit listener a validaci zpracovat v něm.

Pro serializaci pomůže JMSSerializerBundle, který vstupní JSONy “přeleje” do předem definovaných DTO objektů a výstupní DTO objekty zas převede na JSON, který, čerstvě upečený, vyjede uživateli. Pravidla se definují rovněž anotacemi a k dispozici je řada užitečných fičur, např. parametr obsažen až od určité verze API, automatické přejmenování atd.

Domluvu s Elasticem zajišťuje ElasticsearchBundle, který funguje v principu podobně jako Doktrína: dokumenty v Elasticu jsou reprezentovány entitami v PHP aplikaci a ve výkonném kódu se plní jako obraz dat, který bude uložen v Elasticu samotném. Podporovány jsou samozřejmě i nested objects, takže do Elasticu lze narvat entitu i s jejími dětmi a dalšími příbuznými.

Pro geerování swaggří dokumentace je použit Symfony NelmioApiDocBundle, který (jak jinak než z dokumentačních komentářů) strojově vygeneruje swagger JSON. Anotátor umí mimo jiné roztřídit endpointy do skupin, takže privátní část API nebude ve veřejné dokumentaci, ale třeba také endpoint pouze pro API verze 2 nebude v dokumentaci pro verzi 1.

Závěr všeho se, jak už to tak bývá, ukáže až na závěr. Snad to bude dost propečené a nová aplikace přinese zákazníkům i klukům z technické podpory radost a smích.

Vývojový tým vshosting~


Během 17 let jsme provedli úspěšnou migrací stovky klientů. Pomůžeme i vám.

  1. Domluvte se na konzultaci

    Stačí nám zanechat kontakt. Obratem se vám ozveme.

  2. Bezplatný návrh řešení

    Nezávazně probereme, jak vám můžeme pomoct. Navrhneme řešení na míru.

  3. Profesionální realizace

    Připravíme vám prostředí pro bezproblémovou migraci dle společného návrhu.

Zanechte nám svůj e-mail nebo telefon




    Nebo nás kontaktujte napřímo

    +420 246 035 835 V provozu 24/7
    konzultace@vshosting.cz
    Zkopírovat
    Obratem se vám ozveme