Dodo IS-i arhitektuuri ajalugu: varajane monoliit

Või iga õnnetu monoliidiga ettevõte on omamoodi õnnetu.

Dodo IS süsteemi arendamine algas kohe, nagu ka Dodo Pizza äri, 2011. aastal. See põhines äriprotsesside täieliku ja täieliku digiteerimise ideel ja ise, mis tekitas juba siis 2011. aastal palju küsimusi ja skeptilisust. Aga juba 9 aastat oleme seda teed käinud – oma arenguga, mis sai alguse monoliidist.

See artikkel on "vastus" küsimustele "Miks kirjutada arhitektuuri ümber ja teha nii ulatuslikke ja pikaajalisi muudatusi?" tagasi eelmise artikli juurde "Dodo IS-i arhitektuuri ajalugu: tagakontori tee". Alustan sellest, kuidas Dodo IS arendus alguse sai, kuidas nägi välja algne arhitektuur, kuidas tekkisid uued moodulid ja milliste probleemide tõttu tuli teha suuremahulisi muudatusi.

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

Artiklisari "Mis on Dodo IS?" räägib sellest:

  1. Varajane monoliit Dodo IS-is (2011-2015). (sa oled siin)

  2. Tagakontori tee: eraldi baasid ja buss.

  3. Kliendipoolne tee: fassaad üle aluse (2016-2017). (Käimas...)

  4. Päris mikroteenuste ajalugu. (2018–2019). (Käimas...)

  5. Valmis monoliidi saagimine ja arhitektuuri stabiliseerimine. (Käimas...)

Esialgne arhitektuur

2011. aastal nägi Dodo IS arhitektuur välja selline:

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

Arhitektuuri esimene moodul on tellimuste vastuvõtmine. Äriprotsess oli järgmine:

  • klient helistab pizzeriasse;

  • juhataja tõstab telefoni;

  • võtab telefoni teel tellimust vastu;

  • täidab selle paralleelselt tellimuste vastuvõtmise liideses: arvesse lähevad andmed kliendi kohta, andmed tellimuse detailide kohta, tarneaadress. 

Infosüsteemi liides nägi välja umbes selline ...

Esimene versioon oktoobrist 2011:

2012. aasta jaanuaris veidi paranenud

Dodo Pizza infosüsteemi kohaletoimetamine Pizzarestoran

Ressursid esimese tellimuse vastuvõtmise mooduli arendamiseks olid piiratud. Tuli teha palju, kiiresti ja väikese meeskonnaga. Väike meeskond on 2 arendajat, kes panid aluse kogu tulevasele süsteemile.

Nende esimene otsus määras tehnoloogiavirna saatuse:

  • Taustaprogramm ASP.NET MVC, C# keeles. Arendajad olid dotnetchiki, see virn oli neile tuttav ja meeldiv.

  • Bootstrapi ja JQuery kasutajaliides: ise kirjutatud stiilide ja skriptide kasutajaliidesed. 

  • MySQL andmebaas: litsentsitasud puuduvad, lihtne kasutada.

  • Serverid Windows Serveris, sest .NET saaks siis olla ainult Windowsi all (mono-st me ei räägi).

Füüsiliselt väljendus see kõik võõrustaja pühendumises. 

Tellige sissevõturakenduste arhitektuur

Siis rääkisid kõik juba mikroteenustest ja SOA-d kasutati suurtes projektides 5 aastat, näiteks WCF ilmus 2006. aastal. Kuid siis valisid nad usaldusväärse ja end tõestanud lahenduse.

Siin see on.

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

Asp.Net MVC on Razor, mis vormi või kliendi nõudmisel renderdab serveri renderdamisega HTML-lehe. Kliendis kuvavad CSS- ja JS-skriptid juba teavet ja vajadusel täidavad JQuery kaudu AJAX-i päringuid.

Päringud serveris jõuavad *Controller klassidesse, kus meetodis toimub lõpliku HTML-lehe töötlemine ja genereerimine. Kontrollerid esitavad päringuid loogikakihile nimega *teenused. Kõik teenused vastasid mõnele ettevõtte aspektile:

  • Näiteks DepartmentStructureService jagas infot pizzeriate, osakondade kohta. Osakond on pizzeriate rühm, mida juhib üks frantsiisivõtja.

  • ReceivingOrdersService võttis vastu ja arvutas tellimuse koosseisu.

  • Ja SmsService saatis SMS-i, helistades SMS-ide saatmiseks API-teenustele.

Teenused töötlesid andmeid andmebaasist, salvestasid äriloogikat. Igal teenusel oli üks või mitu sobiva nimega *hoidlat. Need sisaldasid juba päringuid andmebaasi salvestatud protseduuride kohta ja kaardistajate kihti. Hoidlates oli äriloogikat, eriti palju aruandlusandmeid väljastavates. ORM-i ei kasutatud, kõik toetusid käsitsi kirjutatud sql-ile. 

Seal oli ka domeenimudeli kiht ja tavalised abiklassid, näiteks tellimuse klass, mis salvestas tellimust. Samas kohas kihis oli abimees kuvateksti konverteerimiseks valitud valuuta järgi.

Seda kõike saab esindada sellise mudeliga:

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

Tellimisviis

Kaaluge sellise tellimuse loomise lihtsustatud esialgset viisi.

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

Algselt oli sait staatiline. Sellel olid hinnad peal ja peal - telefoninumber ja kiri "Kui tahad pitsat - helista numbrile ja telli." Tellimiseks peame rakendama lihtsa voo: 

  • Klient külastab staatilist saiti koos hindadega, valib tooted ja helistab saidil märgitud numbril.

  • Klient nimetab tooted, mida ta soovib tellimusele lisada.

  • Annab oma aadressi ja nime.

  • Operaator võtab tellimuse vastu.

  • Tellimus kuvatakse aktsepteeritud tellimuste liideses.

Kõik algab menüü kuvamisest. Sisselogitud kasutaja-operaator võtab korraga vastu ainult ühe tellimuse. Seetõttu saab vankrikorvi salvestada tema seansse (kasutaja seanss salvestatakse mällu). Seal on Ostukorv, mis sisaldab tooteid ja kliendiinfot.

Klient paneb tootele nime, operaator klikib edasi + toote kõrval ja serverisse saadetakse päring. Andmebaasist tõmmatakse toote kohta info välja ja lisatakse toote info ostukorvi.

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

Märkus. Jah, siin ei saa te toodet andmebaasist tõmmata, vaid edastada selle frontendist. Kuid selguse huvides näitasin andmebaasist täpselt tee. 

Järgmisena sisestage kliendi aadress ja nimi. 

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

Kui klõpsate "Loo tellimus":

  • Taotlus saadetakse aadressile OrderController.SaveOrder().

  • Ostukorvi saame seansilt, tooteid on meile vajalikus koguses.

  • Täiendame Ostukorvi kliendi infoga ja edastame selle ReceivingOrderService klassi AddOrder meetodile, kus see salvestatakse andmebaasi. 

  • Andmebaasis on tabelid tellimuse, tellimuse koosseisu, kliendiga ja need kõik on omavahel seotud.

  • Tellimuste kuvamise liides tõmbab välja uusimad tellimused ja kuvab need.

Uued moodulid

Tellimuse võtmine oli oluline ja vajalik. Sa ei saa pitsaäri teha, kui sul pole müügitellimust. Seetõttu hakkas süsteem funktsionaalsust omandama - ligikaudu aastatel 2012–2015. Selle aja jooksul tekkis palju erinevaid süsteemi plokke, mida ma nimetan moodulid, erinevalt teenuse või toote mõistest. 

Moodul on funktsioonide kogum, mida ühendab mingi ühine ärieesmärk. Samal ajal on nad füüsiliselt samas rakenduses.

Moodulid võib nimetada süsteemiplokkideks. Näiteks on see aruandlusmoodul, administraatoriliidesed, toidujälgija köögis, volitus. Need on kõik erinevad kasutajaliidesed, mõnel on isegi erinev visuaalne stiil. Samas on kõik ühe rakenduse, ühe jooksva protsessi raames. 

Tehniliselt kujundati moodulid Area (selline idee jäi isegi sisse asp.net tuum). Eraldi failid olid nii frontendi, mudelite kui ka oma kontrolleriklasside jaoks. Selle tulemusena muudeti süsteem sellest ...

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

...sellesse:

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

Osa mooduleid realiseeritakse eraldi saitide kaupa (käivitatav projekt), tänu täiesti eraldi funktsionaalsusele ja osaliselt ka veidi eraldiseisva, fokusseerituma arenduse tõttu. See:

  • Saidi - esimene versioon sait dodopizza.ru.

  • Eksport: Dodo IS-i aruannete üleslaadimine 1C jaoks. 

  • Isiklik - töötaja isiklik konto. See töötati välja eraldi ning sellel on oma sisenemispunkt ja eraldi disain.

  • fs — staatika hostimise projekt. Hiljem kolisime sellest eemale, teisaldades kogu staatika Akamai CDN-i. 

Ülejäänud plokid olid BackOffice'i rakenduses. 

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

Nime selgitus:

  • Kassapidaja – restorani kassapidaja.

  • ShiftManager - "Shift Manager" rolli liidesed: pizzeria müügistatistika, võimalus panna tooteid stoppnimekirja, muuta tellimust.

  • OfficeManager – liidesed rollide "Pitseria Manager" ja "Frantsiisivõtja" jaoks. Siin on kogutud funktsioonid pizzeria asutamiseks, selle boonuskampaaniad, töötajate vastuvõtmine ja nendega töötamine, aruanded.

  • PublicScreens – pizzeriates rippuvate telerite ja tahvelarvutite liidesed. Telerid kuvavad menüüsid, reklaamiteavet, tellimuse olekut tarnimisel. 

Nad kasutasid ühist teenusekihti, ühist Dodo.Core domeeniklassi plokki ja ühist baasi. Vahel võisid nad ikka mööda üleminekuid üksteise juurde viia. Sealhulgas üksikud saidid, nagu dodopizza.ru või personal.dodopizza.ru, läksid üldteenustele.

Uute moodulite ilmumisel proovisime maksimaalselt taaskasutada andmebaasis juba loodud teenuste koodi, salvestatud protseduure ja tabeleid. 

Süsteemis tehtud moodulite mastaapide paremaks mõistmiseks on siin 2012. aasta skeem koos arenguplaanidega:

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

2015. aastaks oli kõik kaardil ja veel rohkem oli tootmises.

  • Tellimuste vastuvõtmine on kasvanud eraldi Kontaktkeskuse plokiks, kus tellimust võtab vastu operaator.

  • Pizzeriates rippusid avalikud ekraanid menüüde ja infoga.

  • Köögis on moodul, mis uue tellimuse saabumisel mängib automaatselt häälteate "Uus pitsa" ning prindib ka kullerile arve. See lihtsustab oluliselt köögis toimuvaid protsesse, võimaldab töötajatel mitte lasta end segada paljudest lihtsatest toimingutest.

  • Tarneüksust sai eraldi Delivery Checkout, kus tellimus vormistati eelnevalt vahetusse võtnud kullerile. Palgaarvestuses läks arvesse tema tööaeg. 

Paralleelselt ilmus aastatel 2012–2015 üle 10 arendaja, avati 35 pitsabaarid, juurutasid süsteemi Rumeeniasse ja valmistusid müügipunktide avamiseks Ameerika Ühendriikides. Arendajad ei tegelenud enam kõigi ülesannetega, vaid jagunesid meeskondadeks. igaüks on spetsialiseerunud oma süsteemiosale. 

Probleemid

Sealhulgas arhitektuuri (aga mitte ainult) tõttu.

Kaos baasis

Üks alus on mugav. Järjepidevuse saab selles saavutada ja seda relatsiooniandmebaasidesse sisseehitatud tööriistade arvelt. Sellega töötamine on tuttav ja mugav, eriti kui tabeleid on vähe ja andmeid on vähe.

Kuid 4-aastase arenduse jooksul selgus, et andmebaasis on umbes 600 tabelit, 1500 salvestatud protseduuri, millest paljudel oli ka loogika. Kahjuks ei anna salvestatud protseduurid MySQL-iga töötamisel palju eeliseid. Baas neid vahemällu ei salvesta ning loogika neisse salvestamine raskendab arendust ja silumist. Koodi taaskasutamine on samuti keeruline.

Paljudel tabelitel polnud sobivaid indekseid, kuskil, vastupidi, oli palju indekseid, mis raskendas sisestamist. Modifitseerida oli vaja umbes 20 tabelit – tehing tellimuse koostamiseks võis aega võtta ca 3-5 sekundit. 

Andmed tabelites ei olnud alati kõige sobivamal kujul. Kuskil oli vaja teha denormaliseerimine. Osa regulaarselt laekuvatest andmetest oli XML-struktuuri kujul veerus, mis pikendas täitmisaega, pikendas päringuid ja raskendas arendust.

Samadele laudadele toodeti väga heterogeensed taotlused. Eriti kannatasid populaarsed tabelid, nagu ülalmainitud tabel. tellimuste või tabelid pitsabaar. Neid kasutati köögis tööliideste kuvamiseks, analüütikaks. Teine sait võttis nendega ühendust (dodopizza.ru), kuhu võib igal ajahetkel ootamatult tulla palju taotlusi. 

Andmeid ei koondatud ja paljud arvutused toimusid baasi kasutades käigu pealt. See tekitas tarbetuid arvutusi ja lisakoormust. 

Tihti läks kood andmebaasi siis, kui see poleks saanud seda teha. Kusagil ei olnud piisavalt hulgitoiminguid, kuskil oleks vaja üks päring koodi kaudu mitmeks hajutada, et kiirendada ja usaldusväärsust tõsta. 

Ühtekuuluvus ja hägusus koodis

Moodulid, mis pidid vastutama oma osa äritegevusest, ei teinud seda ausalt. Mõnel neist olid rollide funktsioonid dubleeritud. Näiteks kohalik turundaja, kes vastutab võrgustiku turundustegevuse eest oma linnas, pidi kasutama nii liidest "Administraator" (reklaamide loomiseks) kui ka liidest "Kontorihaldur" (selleks, et näha reklaamide mõju ettevõttele). Loomulikult kasutati mõlemas moodulis sama teenust, mis töötas koos boonuskampaaniatega.

Teenused (ühe monoliitse suure projekti klassid) võiksid üksteisele helistada, et oma andmeid rikastada.

Mudelklasside endi abil, mis salvestavad andmeid, koodiga töötati teisiti. Kuskil olid konstruktorid, mille kaudu oli võimalik kohustuslikke välju määrata. Kusagil tehti seda avalike kinnistute kaudu. Andmete hankimine ja andmebaasist teisendamine oli muidugi mitmekesine. 

Loogika oli kas kontrollerites või teenindusklassides. 

Need tunduvad olevat väikesed probleemid, kuid need aeglustasid oluliselt arengut ja halvendasid kvaliteeti, põhjustades ebastabiilsust ja vigu. 

Suure arenduse keerukus

Raskused tekkisid arenduses endas. Oli vaja teha süsteemi erinevaid plokke ja seda paralleelselt. Iga komponendi vajaduste ühtseks koodiks sobitamine muutus üha keerulisemaks. Ei olnud lihtne kokku leppida ja meeldida kõigile komponentidele korraga. Sellele lisandusid tehnoloogia piirangud, eriti mis puudutab baasi ja esiosa. JQueryst oli vaja loobuda kõrgetasemeliste raamistike suunas, eriti klienditeenuste (veebi) osas.

Mõnes süsteemi osas võiks kasutada selleks sobivamaid andmebaase.. Näiteks kasutasime hiljem tellimuste ostukorvi salvestamiseks Redisest CosmosDB-sse kolimist. 

Oma valdkonnaga seotud meeskonnad ja arendajad soovisid selgelt oma teenuste jaoks suuremat autonoomiat nii arendamise kui ka kasutuselevõtu osas. Ühendage konfliktid, vabastage probleemid. Kui 5 arendaja jaoks on see probleem tähtsusetu, siis 10 ja veelgi enam kavandatud kasvu korral muutuks kõik tõsisemaks. Ja ees ootas mobiilirakenduse arendamine (see algas 2017. aastal ja 2018. aastal suur kukkumine). 

Süsteemi erinevad osad nõudsid erinevat stabiilsuse taset, kuid süsteemi tugeva ühenduvuse tõttu ei saanud me seda pakkuda. Viga uue funktsiooni väljatöötamisel administraatoripaneelis võis vabalt aset leida saidil tellimuse vastuvõtmisel, sest kood on ühine ja korduvkasutatav, andmebaas ja andmed on samuti samad.

Tõenäoliselt oleks sellise monoliit-moodularhitektuuri raames võimalik neid vigu ja probleeme vältida: teha vastutusjaotus, refaktoreerida nii kood kui andmebaas, eraldada selgelt kihid üksteisest, jälgida kvaliteeti iga päev. Kuid valitud arhitektuursed lahendused ja keskendumine süsteemi funktsionaalsuse kiirele laienemisele tõid kaasa probleeme stabiilsuse osas.

Kuidas The Power of the Mind ajaveeb restoranides kassasid pani

Kui pizzeriavõrgu (ja koormuse) kasv jätkuks samas tempos, siis mõne aja pärast oleks kukkumised sellised, et süsteem ei tõuseks. Näitab hästi probleeme, millega hakkasime silmitsi seisma 2015. aastaks, siin on selline lugu. 

Blogis "Meele jõud” oli vidin, mis näitas andmeid kogu võrgu aasta tulude kohta. Vidin pääses juurde Dodo avalikule API-le, mis neid andmeid pakub. See statistika on praegu saadaval aadressil http://dodopizzastory.com/. Vidinat näidati igal lehel ja see esitas taimeriga päringuid iga 20 sekundi järel. Taotlus läks aadressile api.dodopizza.ru ja palus:

  • pizzeriate arv võrgus;

  • võrgu kogutulu aasta algusest;

  • tänase päeva tulu.

Tulude statistika päring läks otse andmebaasi ja hakkas küsima andmeid tellimuste kohta, koondama andmeid käigult ja andma välja summat. 

Restoranide kassad läksid samasse tellimuste tabelisse, laadisid maha tänaseks laekunud tellimuste nimekirja ning sinna lisandusid uued tellimused. Kassaaparaadid esitasid oma päringud iga 5 sekundi järel või lehe värskendamise järel.

Diagramm nägi välja selline:

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

Ühel sügisel kirjutas Fjodor Ovtšinnikov oma blogis pika ja populaarse artikli. Blogi tuli palju inimesi ja hakkas kõike hoolikalt lugema. Sel ajal, kui kõik kohale tulnud inimesed artiklit lugesid, töötas tuluvidin korralikult ja taotles API-d iga 20 sekundi järel.

API kutsus välja salvestatud protseduuri, et arvutada kõigi keti pizzeriate tellimuste summa alates aasta algusest. Koondamisel võeti aluseks tellimuste tabel, mis on väga populaarne. Sinna lähevad kõik sel ajal avatud restoranide kõik kassad. Kassad lakkasid reageerimast, tellimusi vastu ei võetud. Samuti ei võetud neid saidilt vastu, ei ilmunud jälgijale, vahetuse juht ei näinud neid oma liideses. 

See pole ainuke lugu. 2015. aasta sügiseks oli igal reedel süsteemi koormus kriitiline. Mitu korda lülitasime avaliku API välja ja üks kord pidime isegi saidi välja lülitama, sest miski ei aidanud. Seal oli isegi nimekiri teenustest, mille seiskamiskäsk on suure koormuse korral.

Nüüdsest algab meie võitlus koormustega ja süsteemi stabiliseerimise eest (sügis 2015 kuni sügis 2018). Siis see juhtus"suur sügis". Edasi tuli vahel ette ka tõrkeid, mõned olid väga tundlikud, kuid üldise ebastabiilsuse perioodi võib nüüd möödanuks lugeda.

Kiire ärikasv

Miks ei saanud seda kohe teha? Vaadake lihtsalt järgmisi diagramme.

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

Ka aastatel 2014-2015 oli avamine Rumeenias ja ettevalmistamisel avamine USA-s.

Võrgustik kasvas väga kiiresti, avati uusi riike, tekkisid uued pizzeriaformaadid, näiteks avati pizzeria toiduväljakul. Kõik see nõudis märkimisväärset tähelepanu just Dodo IS funktsioonide laiendamisele. Ilma kõigi nende funktsioonideta, köögis jälgimise, toodete ja kadude arvestamiseta süsteemis, tellimuse väljastamise kuvamiseta toidukohtu saalis, vaevalt räägiksime "õigest" arhitektuurist ja "õigest" lähenemisest. areng praegu.

Teine takistus arhitektuuri õigeaegsele ülevaatamisele ja üldiselt tehnilistele probleemidele tähelepanu pööramisel oli 2014. aasta kriis. Sellised asjad mõjutavad tugevalt meeskondade kasvuvõimalusi, eriti sellise noore ettevõtte jaoks nagu Dodo Pizza.

Kiired lahendused, mis aitasid

Probleemid vajasid lahendusi. Tavaliselt võib lahendused jagada kahte rühma:

  • Kiired, mis kustutavad tule ja annavad väikese turvavaru ning annavad meile aega muutuda.

  • Süsteemne ja seetõttu pikk. Mitmete moodulite ümberprojekteerimine, monoliitse arhitektuuri jagamine eraldi teenusteks (enamik pole üldse mikro-, vaid pigem makroteenused ja selles on midagi Andrei Morevski aruanne). 

Kiirete muudatuste kuiv nimekiri on järgmine:

Suurendage baasmeister

Loomulikult on esimene asi, mida koormustega toime tulla, serveri võimsuse suurendamine. Seda tehti põhiandmebaasi ja veebiserverite jaoks. Paraku on see võimalik ainult teatud piirini, siis läheb see liiga kalliks.

Alates 2014. aastast oleme kolinud Azure’i, sel teemal kirjutasime ka toona artiklis “Kuidas Dodo Pizza Microsoft Azure'i pilve abil pitsat tarnib". Kuid pärast baasi serveri arvu mitmekordset suurendamist tulid nad maksma. 

Aluskoopiad lugemiseks

Aluse jaoks tehti kaks koopiat:

Replica lugemine viitetaotluste jaoks. Seda kasutatakse kataloogide, tüübi, linna, tänava, pizzeria, toodete (aeglaselt muudetud domeen) lugemiseks ja nendes liidestes, kus väike viivitus on vastuvõetav. Neid replikaid oli 2, tagasime nende kättesaadavuse samamoodi nagu meistrid.

Lugege aruandetaotluste koopiat. Sellel andmebaasil oli madalam saadavus, kuid kõik aruanded läksid sellele. Las neil on suuri taotlusi andmete tohutuks ümberarvutamiseks, kuid need ei mõjuta põhiandmebaasi ja tööliideseid. 

Vahemälud koodis

Koodis ei olnud kuskil vahemälu (üldse). See tõi kaasa täiendavaid, mitte alati vajalikke päringuid laaditud andmebaasi. Vahemälud olid esmalt nii mälus kui ka välises vahemäluteenuses, see oli Redis. Kõik oli ajaliselt kehtetu, seadistused olid koodis täpsustatud.

Mitu taustaserverit

Suurenenud töökoormusega toimetulemiseks tuli skaleerida ka rakenduse taustaprogrammi. Ühest iis-serverist oli vaja teha klaster. Oleme ajakava muutnud rakendusseanss mälust RedisCache'i, mis võimaldas teha mitu serverit lihtsa koormuse tasakaalustaja taha koos round robin'iga. Algul kasutati sama Redist, mis vahemälude jaoks, siis jagati mitmeks. 

Selle tulemusena on arhitektuur muutunud keerulisemaks ...

Dodo IS-i arhitektuuri ajalugu: varajane monoliit

… kuid osa pingest oli eemaldatud.

Ja siis oli vaja laetud komponendid ümber teha, mille ka ette võtsime. Sellest räägime järgmises osas.

Allikas: www.habr.com

Lisa kommentaar