MALL Group tvoří největší e-commerce skupinu ve střední a východní Evropě. Sdružuje více než dvě desítky e-shopů zabývajících se prodejem širokého portfolia produktů od elektroniky po potraviny.
Pro Mall.cz jsme pracovali na několika zajímavých projektech, každý má svá specifika...
Shopping
Mall.cz
Web
Marketingové oddělení mall.cz potřebovalo nástroj, jehož pomocí bude moci rychle a dle aktuálních potřeb udělat změny v menu webu, například pro sezónní zboží, různé akce, apod. Zároveň bylo třeba zajistit, aby se ukládala historie změn a v případě potřeby bylo možné se k jednotlivým úpravám vracet.
Hlavní výzvou bylo, jak ukládat data tak, aby byla snadno udržená historie změn v menu: jaké úpravy kdo a kdy vytvořil. Dále pak také propagace změn jako takových až k zákazníkovi na web.
Pro uložení dat jsme využili tzv. event stream a snapshotting. Data se v takovém případě neukládají jako celek, ukládají se pouze operace, které se s daty provádí. Aplikací těchto událostí na výchozí stav se dostaneme k výsledným datům.
Základními operacemi je vytvoření / editace a smazání položky. Výchozím stavem je prázdné menu.
Důležitým faktorem je to, jak jednotlivé operace přicházejí za sebou. Vždy se musí při aplikaci operací postupovat od nejstarších po nejnovější.
Díky tomuto systému jsme schopni ke každému časovému okamžiku sestavit přehled, jak data v daném čase vypadala. Když ke každému záznamu přidáme i uživatelské informace, máme pak rovnou vyřešený výpis historie, protože jasně víme, jaké operace, v jakém čase a kdo provedl.
Problém ale nastane v případě, kdy je nutné aplikovat hodně eventů najednou. Není dobré vycházet vždy z původního stavu, protože aplikace všech eventů postupně bude časově narůstat. Tento problém redukuje snapshotting. Jedná se o průběžné ukládání výsledného stavu dat v konkrétní čas. Máme-li nějaký stav v čase uložený, pak se k dalšímu stavu dostaneme aplikováním událostí od tohoto času dál. Dejme tomu, že ukládáme snapshoty s každým stým eventem. Máme pak jistotu, že se od předchozího stavu k aktuálnímu dostaneme vždy po aplikování maximálně 100 událostí, a jsme schopni počítat s konstantním časem na sestavení aktuálního stavu dat.
Během implementace a používání vyplynuly některé nedostatky zvoleného systému. Jeho plusy však stále výrazně převyšují mínusy.
Systém se nehodí se na velké množství dat, ve kterých by se mělo vyhledávat. Výsledný snapshot a všechny operace s ním se udržují v paměti. V systému nelze použít klasické metody pro vyhledávání v databázových systémech. Ty ale v tomto systému nejsou potřeba. Vyhledávání je totiž požadované jen na vrchní úrovni dat a to jsme byli schopni aplikačně optimalizovat. pokud jsou data udržovaná v paměti, je navíc práce s nimi velice rychlá.
Dalším nedostatkem je oprava bugů. Aby byla data v čase vždy konstantní a mohli jsme je sestavit od začátku do jakéhokoliv bodu, musíme v kódu udržovat i zpracování událostí s bugem. Do chvíle, než se bug odstraní, jsou data stále vyvíjena stále s bugem. Od odstranění bugu se data vyvíjí již bez něj, musejí však kvůli tomu vznikat nové typy událostí.
Museli jsme vyřešit problém distribuce dat mezi jednotlivými instancemi, což se děje asynchronně přes messaging systém rabbitMQ.
Dále jsme ochránili data tak, že výsledek je vždy uložen staticky v souboru na HA online storage, takže existuje fallbackové řešení pro případ, že služba nebude dostupná. Díky tomu zajistíme, že se menu k webu vždy dostane.
Postavili jsme systém, který má kompletní historii, lze se snadno vracet k dřívějším verzím dat a rychle poskytuje požadovaná data klientům.
TypeScript, Node.js, MongoDB, RabbitMQ, Azure Storage
Shopping
Mall.cz
Web
Jednou z krizových oblastí každé webové aplikace je rychlost načítání obrázků. Cílem práce vývojářů je to, aby si uživatel vlastně ani nevšiml, že se mu nějaké obrázky načítají. Pokud si všimne, není to dobré znamení a nikdo by se v takové situaci uživateli nedivil, kdyby z e-shopu z tohoto důvodu odešel.
MALL jako jedna z největších e-commerce platforem v rámci Evropy musí optimalizovat načítání webové aplikace, tak aby probíhalo co možná nejrychleji. S tím samozřejmě souvisí i rychlé načítání obrázků. MALL jako e-shopové řešení zobrazuje mnoho různých produktů na mnoha rozličných fotografiích. My jsme pracovali na řešení, které vhodně optimalizuje prakticky jakýkoliv vstupní obrázek do co možná nejmenšího výstupního komprimovaného obrázku. Zároveň jsme chtěli využít potenciál next gen image formátů jako je webp a vyrovnat se se skutečností, že ne všechny prohlížeče daný formát využívají.
Největší výzvou v rámci projektu bylo se vyrovnat s několika faktory.
Museli jsme se vyrovnat s velkou variabilitou vstupních dat. Vstupní obrázky jsou často nahrávány strojově a není zaručena jejich kvalita. Kromě toho, že jsme si museli poradit prakticky s jakýmkoliv typem obrázku, museli jsme být připraveni i na “rozbité” obrázky, poškozené hlavičky obrázku atd.
Mall má ve svém sortimentu zalistováno více než milion produktů. Každý takový produkt má na sebe navázáno mnoho fotografií. My jsme museli připravit řešení, které dokáže optimalizovat až miliony obrázků denně. Jelikož jsme použili metody velké komprese a někdy pracujeme i s poměrně velkými obrázky, jedna komprese může trvat i desítky sekund. Bylo tedy zapotřebí se architektonicky připravit na takový load.
Pro ještě lepší načítání optimalizujeme ad hoc do několika různých kvalit. Aktuálně se používají 3 různé kvality obrázků a dva typy výstupů - jpeg/png nebo webp. Do budoucna je tak možno docílit toho, že pro mobilní zařízení se budou načítat primárně obrázky menší a méně kvalitní než pro desktopové zařízení.
Rozhodli jsme se pro AWS serverless řešení kvůli velmi variabilnímu škálování služby. Jsme tak schopni celé řešení škálovat během velmi krátké doby a optimalizovat tak miliony obrázků.
Celá služba pracuje zcela nezávisle na jiné službě. Proto, abychom dokázali rychle měnit průtok danou službou, jsme připravili REST API, které funguje pouze na příjem požadavků na optimalizaci. Jeho cílem je předat požadavek k optimalizaci do fronty a současně předat informaci žadateli o tom kde výsledný obrázek nalezne.
Poté probíhá samotná optimalizace obrázků. Pracujeme se dvěma variantami. Nejdříve probíhá velmi agresivní komprese, která dokáže obrázek optimalizovat na dřeň ale zároveň vizuálně beze změny. Nicméně v mnoha případech (přibližně pod 1 procento všech obrázků) se nepodaří obrázek optimalizovat. Pro tyto případy používáme záložní variantu, která dokáže zoptimalizovat (i když ne tak dobře) prakticky každý obrázek.
Během procesu jsme se museli vyrovnat s velkou rozlišností vstupních obrázků, avšak s jedním nastavením výsledné optimalizace. V jednom z řešení jsme počítali i se spuštěním více optimalizací a následným porovnáním s původním obrázkem – tj. vybrat ten typ optimalizace, který vizuálně nedestruuje výsledný obrázek strojově. Po několika testech měření se však ukázalo, že ve většině případů vítězí jedna metoda.
Výsledné řešení dosahuje již po prvním nasazení úspory kolem 30 procent. Po nasazení převodu do next gen formátů jsme se dostali až přes 60 procent. Výsledek celé akce jsme také měřili po nasazení první fáze (bez next gen formátu). Měřili jsme pomocí ukazatele dom content loaded, kdy jsme se zlepšili jak u mobilních tak u desktopových zařízení o více než jednu sekundu.
Node.js, AWS, Amazon CloudFront
Shopping
Mall.cz
Web
Zákazníci e-commerce si možná neuvědomují, že rozsáhlé e-shopy jsou téměř permanentně vylepšovány velkými týmy vývojářů tak, aby průběh nákupu byl pro uživatele stále více přívětivý a jednoduchý. Je třeba věnovat pozornost i takovým jednotlivostem jako je hlášení chyby, která může zákazníka odradit od dalšího nákupu. Objeví-li se na stránce chyba, je třeba ji co nejdříve nahlásit, aby došlo k rychlé nápravě. My jsme pro MALL pracovali na aplikaci, která dokáže kdekoliv na webu vyvolat formulář pro hlášení chyby. Tento formulář se po odeslaní dostane do systému JIRA a zde se založí požadavek s veškerými údaji a detaily tak, aby byla chyba co nejlépe specifikována a mohla tedy být co nejrychleji vyřešena.
Jedná se o aplikaci, která umožňuje:
V rámci projektu bylo největší výzvou vyrovnat se s několika faktory.
Samotný prohlížeč nepodporuje printscreen, který by bylo možné hned odeslat. Vyzkoušeli jsme různé knihovny a nakonec použili Html2canvas, který umí na pozadí znovu postavit DOM a udělat printscreen pro lepší orientaci. Obrázek je následně oříznut na pozici a velikost okna prohlížeče.
Kvůli tomu, že je aplikace stažena z jiné domény a je integrována do webové stránky, nemůže aplikace stahovat obrázky z domény, na které se zrovna nachází (same-origin policy). Proto jsme vytvořili proxy server, do kterého se odešle odkaz na obrázek a obrázek se mu vrátí zpět.
Obrázky se uloží u 3.strany, aby JIRA nehromadila obrázky, a odkaz na obrázek společně s metrikami prohlížeče založí ticket v JIRA. Tam také dochází k ověření přes oauth2.
Jedná se o jeden script, který se po kliknutí nebo zmáčknutí klávesové zkratky nainicializuje do hlavičky a spustí aplikaci. Aplikace umožňuje překlady nebo lze měnit nastavení přes globální proměnnou.
Pro výsledné řešení jsme na frontendu použili React a server Node-JS, což je služba, která běží v AWS EC2 ve více instancích s využitím AWS s3 a AWS SES na odesílaní emailu. Služba by klidně mohla běžet na AWS serverless (Lambda).
Na serveru je express který zachytí POST požadavek z frontendu, ten odešle zprávu, obrázek a data o prohlížení, následně obrázek převede do base64 tak, aby se obrázek dal uložit jako string, a všechna data se uloží na AWS s3. Poté dochází k odeslání do JIRA, kde se založí ticket, který má specifické nastavení, např. ze byl podle emailu založen určitým uživatelem.
V případě chyby je v systému JIRA je založen ticket, který má nastaveny všechny parametry důležité pro řešení chyby: lze se podívat na obrázek a na metriky prohlížeče a je také vidět, který uživatel ticket zadal. Helpdesk tak může uživatele hned kontaktovat nebo chybu okamžitě opravit.
TypeScript, Node.js, React.js, Canvas, Amazon SES
Copyright © 2013 - 2024 Všechna práva vyhrazena