5. ”
…the microservice architectural style is an approach
to developing a single application as a suite of small
services, each running in its own process and
communicating with lightweight mechanisms, often
an HTTP resource API.
- Martin Fowler
6. 12factor application
1. Codebase
2. Dependencies
3. Config
4. Backing services
5. Build release run
6. Process
7. Port binding
8. Concurrency
9. Disposability
10.Dev/Prod parity
11.Logs
12.Admin process
7. Microservices patterns
•Service communication HTTP/AMQP or
asynchronous protocols
•API gateway
•Service discovery
•Multiple service instances per host
•Serverless deployment
•Database per Service
•Event-driven architecture
•Database triggers
Udvozlok mindenkit!
Papp David vagyok a ghostmonitornal dolgozom mint Chief Architect. A feladatom az ,hogy a fejlesztes, infrastruktura es minden ami DevOps az hozzam tartozik a cegnel. 1 evvel ezelott is eloadtam ezen a koferencian koszonom ,hogy ujra itt lehetek akkor meg eleg kezdok voltunk a microservices dolgokban akkor meg csak arrol szolt a dolog ,hogy mit tervezunk most megnezzuk mit tanultunk es hova juttotunk. Az eloadas egy altalanos kepet fog festeni milyen problemakkal kell megkuzdeni ,hogy eljussunk egy mukodo rendszerhez es mi milyen problemakkal kuzdotunk meg es ezeket ,hogyan oldotuk fel.
Kik is vagyunk mi?
A cegunk 2015 majusaban jott letre de az otlet mar ennel korabban felvetotod az alaptiokban. A jelenlegi csapatletszam korulbelul 11 fobol all. Ezeknek a nagyresze fejleszot. A cegunket tenktive mi egy e-commerce analytics platform vagyunk.
Az eredeti problema amiert letre jott maga a ceg az a kosar elhagyas(cart abdonment)
Aki foglalkozik webshoppal az mindneki szembesul ezzal a problemaval ,hogy elkezdi az ugyfel vasarlast majd nem fejezi be. Ez a szam egy webshop eseten korulbelul 70-30%-ban oszlik meg. Szoval az emberek 70% el hagyja a kosarat mi ezen probalunk segiteni.
Milyen technologiakat hasznalunk a cegnel?
AWS – Amazon WebServices
Docker
NodeJS
Codeship
Terraform
CoreOS
MongoDB
Elasticsearch
Az elaodasom temaja ,hogy microservices uzemeltetoi szemmel… de eloszor is tisztazzuk ,hogy mi az a microservices es amugy miert jo ez az egesz azon kivul ,hogy jol megszivatjuk magunkat …. ,hogy tul bonyolitunk egy jo nagy rendszer sok kicsivel.
Hagyj idot elolvasni.
Egy martin flower nevu uriember szepen osszefoglalta nekunk ,hogy mi is az a microservices. Ez egy olyan architecturalis megoldas ami kulon allo applickaciokat kapcsol osszes egy egyszeru protokkolon keresztul pl. HTTP.
Most ,hogy mar ismerjuk korulbelul a microservices fogalmat ismerkedjunk meg azzal a 12 alap szabalyal amit erdemes figyelembe venni az alkalmazas es az infrastruktura megtervezesenel. Ez a 12 szabaly segiteni fog nekunk abban ,hogy egy jol atgondolt rendszert kapjunk. 12 szabaly esetleg 12 megoldando problemat is hasznalhatnank erre.
Gyorsan vegyunk parat vegig:
Codebase -> Legyen egy kozponti taroloba tarolva a kodjaink. Ezt annyira nem nehez megugorni.
Tudjunk depedenciakat kezelni -> Compose, NPM, GEM …stb
Environmentbol konfigrulhatoak legyenek – kulonbozo konfig valtoztatasok -> Hogy ez miert jo? Hat mert nem kell ujra deployolni az alkalmazast eleg csak oket szep sorba ujra inditani.
Backing services -> Itt arra gondolt a kolto ,hogy mivel nagyon sok hater szerveziunk van meg kell oldanunk azt a problemat ,hogy tudjanak beszelgetni ezaltal szuksegunk lesz valamilyen service discovery megoldasra. Elosztott rendszerekrol leven szo ez nem olyan elhanyagolhato problema de konnyen meg lehet csinalni.
Itt igazabol arrol van szo ,hogy allitsunk elo egy olyan artifactot vagy imaget amit futtatni fogunk. A mi esetunkben ez a Docker image jelenti.
Torekedjunk arra ,hogy minden szervizunk stateless legyen.
Ez igazabol nem annyira fontos egy fix porton figyeljen a service de ezt a legtobb rendszer lekezelni nekunk.
Gondoljunk az esetleges skalazasi problemakra.
Eldobhatosag -> Ne taroljunk adatokat magaba a szervezikbe erre hasznaljunk valami object storage megoldast vagy barmilyen persistance storageot. Fontos ,hogy a szervizek indulas es lealassa gyors legyen. Pl. ha nagyobb request szam beesik a rendszerbe es a rendszernek reagalnia kell akkor nem mindegy mennyi ido alatt indul el egy szerviz. Ez a mi esetunkben egy viszonylag fontos dolog. Ugyan is mi nem ismerjuk az ugyfeleink latogatotsagat es ha nagyobb request szam beesik akkor arra nekunk reagalni kell a rendszer leallasa/kieses nelkul.
A staging/prod kornyezetunk egyezzen meg igy elkerulhetok legyen esetleges az integracios hibak. Erre nekunk az a megoldasunk ,hogy Kubernetes egy clusterben fut mint ket kornyezet de ugyelve arra ,hogy a staging esetleges hiba eseten ne tudja bedonteni az eles oldalt igy eroforras korlatozas van bevezetve minden servicre. De az eles rendszerben ugyan ugy termeszetesen magasabb ertekkel.
A logolas hat ez az a masik nagy problema amivel szembe kell nezni ha egy microservices architecturat kezdunk el epiteni. Ugyan is a logokat nem csak el kell tudnunk nyelni hanem ezeket fel is kell tudni dolgozni es mondjuk riasztasokat kell csinalni. Ugyan is a monitorozo rendszerrel egyutt nagyon jol ki tudjuk egesziteni a problemak feltarasat esetleg elore tudunk jelezni dolgokat.
Kulonitsuk el az admin feladatokat az eredeti alkalmazastol. Adatbazis takartitas…analitkak
Maga a microservices ugy-e egy elmelet egy megkozelites ezert nincs semmien szabvany ami leirana mikent is kellene egy ilyen rendszert megepiteni ezert is szep ez az egesz.
Par ember viszont meg fogalmazott par hasznos patternt ami jo ha betartunk kulonben szivni fogtok mint mi .
A szervizeink valamilyen aszinkron protokolon keresztul beszlegessnek pl. HTTP vagy AMQP vagy valamilyen aszinkron protokollon keresztul.
Hasznaljunk API gateway-t amin keresztul bejonnek a keresek es tudjuk esetlegesen korlatozni a bejovo forgalmat es a megfelelo szervizhet iranyitani.
Service discovery errol meg lesz ezt kicsit kesobb kifejetem.
Tobb service fusson egy darab instancesen ezt kell tul magyarazni sokkal hatekonyabban ki tudjuk hasznalni az eroforrasokat.
Serverless deployment ez ugy-e az uj trend mint pl. AWS lambda ,hogy feltoltunk egy zippet amibe minden be van csomagolva es fut valahol mi meg orulunk neki.
Errol is lesz szo hamarosan.
Event-driven architecture es Database triggers itt nem olyan adatbazis triggerekre kell gondolni mint ami mysql-be. Nemtudom ki mennyire ismermi a dynamodb-t abba van lehetoseg olyanra, hogy ha egy esemeny bekovetkezik pl. az adatbazisban modosult egy ertek ami ugy-e egy update akkor az generaljon egy eventet. Igy egy esemeny vezerelt arhitecturat tudunk epiteni.
Egy service csak egy tablat irhat.
Mivel elosztott rendszerekrol beszelunk eleg nagy problema lenne ,hogy ha minden egyes szerviz ami szeretne hozza ferni az adatbazishoz elkezdne irni. Ugyan is akkor minden szerviznek ismerni kellene az adatbazis semat.
Gondolom eltudjatok kepzelni mi tortenne ha 1-nel tobb helyen kellene ugyan azt adatbazis semat modositani. Igy viszont az osszes szerviz egy REST API-t lat amit hivogat hat es ha szuksege van egy vagy tobb adatra akkor azt elkeri egy masik servicetol. Ez a model biztositja nekunk azt is ,hogy nem kell ugyan azt az adatbazis motort hasznalni minden szerviz alatt hanem ez viszonylag konnyen tudjuk modositani egyik nap mongodb van mogotte a masik nap meg mar mondjuk egy mysql.
El is erkeztunk az eloszott rendszerek masik problemajahoz meg pedig ,hogy talaljunk meg egymast mikozben minden dinamikus es minden valtozik semminek sincs fix ip cime vagy fix portja. Ugy-e amikor a rendszerunk elejen vagyunk ebbe a problemaba bele se gondolunk amig mondjuk van 5-6 szerveziunk de amikor ez a szam elkezd drasztikusan novekedni akkor ez a problema hamar szembe fog velunk jonni. Az se szerencses ha ezeket beegetjunk szepen a konfigokba mert akkor egy esetleges valtoztatas eseten a szerviz osszes depedenciajat ujra kellene deployolni nem lenne tul szerencseses.
!!!Plusz kep bejon…
Erre nyujt nekunk megoldast a service discovery minden service ami elindul az beirja magat a service registry-be amikor pedig leall akkor a rendszer kiveszi ot a kiszolgalasbol. A service discoverynek ket legismertebb modja az DNS es az ENVIRONMENT alapu. Mi mind a kettot hasznaljunk amennyiben pl. DNS nem megy ez esetben fallbackelunk ENVIRONMENT-re.
Felsoroltam eloszor ezt a 4 problemat ami egybol szembejott amikor ki talatuk ,hogy mi szeretnenk ilyen szep elosztott rendszer epiteni…hat igen ezt tok jo milyen jo lesz ez nekunk igen de mivel is valositsuk meg ezeket.
Eloszor is szuksegunk volt valami frameworkre az elozo rendszer eleg vegyes volt tartalmazott Sails meg Express-t vegyesen valahogy ezt az alaptotott fel kellet oldani le lovom a poet a valasztas nem ezekre esett.
Ott volt a lokalis fejlesztes problema ez maig nem teljesen megoldott problema viszont mar van ra egy viszonylag jol bevalt megoldasunk.
Hat valahogy tesztleni is kellene azokat a franya szerveziket es nem csak mockolt adatokkal. Igen am de itt is szembe jott par problema…
Ezekbol a kodobol kellene csinalni valami Docker image-t is fabrikalni lovagoljuk mar meg a trendeket.
Jojon a kovetkezo 4-s csoport…
Ohh…hat ha mar le buildeltuk a docker imageket akkor azokat valahogy ki is kellene deplyolni valami infrastrukturara
Ha mar van deployerunk akkor valamin futtasuk mar ezeket az imageket….
Igen…igen futnak csucsszuper meg is kellene nezni mit csinalnak ezeket a frana szervezinek biztos nem mukodik mindig jol…hat nem…
Tok jo ,hogy monitorozzuk oket de azert jo lenne tudnunk mi tortenik a lelkukbe es valami informaciot kikopnek az eljutna hozzank valami strukturalt formaba.
Nezzuk is az elso jatekost a framework problema. Alapvetoen hive vagyunk annak az elvnek ,hogy nekunk problemakat kell megoldani es nem programozunk kell viszont van amikor kompromisuzmokat kell kotni. A Koa framework egy eleg minimal dolog de azert ez mellet viszonylag sok mindent nyujt nekunk. Nem er fel mondjuk egy Express vagy Sails kepessegeivel viszont biztositja nekunk azt ,hogy a szervezinek ne legyenek tulsagosan eroforras igenyesek. Az atlag szervziek 128MB rammal nagyon szep elfutkaroznak.
Szuksegunk volt egy kozponti LIB-re amit minden szerviz behuzz es tud hasznalni. Szukseg volt arra ,hogy modularis legyen nem minden szerviznek van szuksege minden funkciora pl. egy API-nek nincs szuksege MongoDB-re de szuksege van Service Discoveryre es mondjuk REDIS-re. Viszont ha kesobb szukseg van barmilyen extra dologra akkor csak be kapcsoljuk az adott szervizre es mar lehet is hasznalni.
Most ,hogy mar van frameworkunk meg alkalmazasunk ezt akkor csomagoljuk mar be ,hogy hordozhato image-be ami a mi esetunkbe a Docker lett. A lokalis fejleszteshez szukseg van Docker-compose vagy dockerre ugyan is a kulonbozo dependeciakat valahogy futtatnunk kell magunknal de maga a fejlesztes nem dockeren belul csinaluk azt siman a megszokott modon tortenik. A dolog annyiban bonyolodik ,hogy ha a olyan szervizt fejlesztunk aminek sok a dependiciaja akkor akar 10-15 docker is futhat a gepukon ami azert a regebbi gepeknek eleg megterhelo lehet. Viszont mivel van environment alapu service-discoverynek ezert ezeket ugyan beallitjuk lokalba es megfogja talalni lokalisan futtatot szerviz a dockerben futokat.
A Jet a codeship nevezetu CI-nak a termeke amivel localba lehet futtatni ugyan azokat a dolgokat mint fent. Igy localba is ki tudjuk probalni mi fog torteni CI kornyezetben.
Minikube es Kube-Solo pedig abban segit ha van valami kubernetes specifikus problemank vagy big picture akarjuk latni localba akkor ezeket futtatjuk es ugyan azt vegre tudjuk hajtani mint fent az eles vagy staging rendszerbe.
A rendszerben egyarant megtalalhato unit test – e2e test – integration test. Mi is figyeljuk a codecoveraget meg a code complexity-t erre a Codeclimate nevu termeket hasznaljuk.
Szeretjuk a valosaghu teszteket ami az jelenti amennyire lehet nem mockolt teszteket hasznalunk hanem van lehetosegunk teszteles es buildeles kozben behivni mas szerveziket igy tudjuk tesztelni kozel azt az allaptot mint ami eles vagy staging kornyezetben megtortenik.
Itt a buildelesnel fontos meg emeliteni meg egy fontos problemat ugyna is a dockernek van egy ”kis” hibaja ami nem is olyan kicsit es eleg gyorsan szembe fog velunk meg pedig nem tud kezelni inditasi sorrendeket szoval egy mas dependciai nem sorrendben fognak elindulni hanem ossze vissza szoval erre a problemara jobb ,hogy fel keszulunk. Mindenkinek a sajat rendszerben erre megoldast kell talalnia.
A codeship services fileban tudjuk meghatarozni ,hogy az adott buildhez milyen szervizeket huzunk be a buildelesnel. Ebben az esetben mongodb de itt adhatjuk meg az elobb emlitett tobbi backend szervizt amit szuksegunk van.
Codeship-steps
Itt adahatjuk meg azokat a parancsokat amiket a kodon vegre kell hajtania buildeles kozben. A commandokat tudjuk kulonbozo branchrek korlatozni.
Nezzuk gyorsan at a fajlt.
Az elso sor servce: app ez minden build eseten lefut. Az npm install azert fut itt le mert ezek a buildek meg nem artifactory alapuakra ugyan is nodejsnel is szukseg volt a sok package miatt amire szukseg lett. Az atlag szerviz meret az 100-200MB volt az artifactes build utan pedig 37MB-t. Beszeltunk a 12 szabalynal ez a 9-es szabalyhoz tartozik ugyan is amikor le kell tolteni a szerverek minden egyes buildnel mondjuk 100-200MB-t ha ez leviszuk a 37MB mar is drasztikusan csokkeni fog a deployolasi ido.
A push nekunk a deplyolas a commit_id tag-re epul igy sokkal konnyebben tudunk rollbackelni.
Ez egy altalunk kifejlesztett sajat deployer. A feladata az ,hogy a codeship webhookokat feldolgozva elo allitatsa a template fileokat vagy veghez vigyen egy rolling-updatet. A kettot kozott annyi a kulonbseg mig az egyik eseten maga a template valtozik a masik eseten csak uj imaget rakunk ki a rendszerbe.
A deployer maga ugy mukodik ,hogy van egy API resze az megkapja a hookot ezt feldolgozva berakja egy queue-ba ami jelen esetben REDIS majd innen a workerek kiveszik es feldolgozak az adott feladatot. Ha vegezetke akkor kuldenek rola egy notification-t slack channelbe.
Rollback -> jelenleg ez meg terv de hamarossan megvalositasra kerul. Ennek van egy beepitett modja ,hogy ha a deployolas kozbe hiba csuszik pl. nem tud elindulni a szerviz akkor a deploy automatikusan megszakad.
Template management
Kezeli a kulonbozo szervizek eroforrasat
A szervizek verzio kezelest
Environment valtozok
AWS kulcsok
MONGO_URI
REDIS_URI