Historia om Dodo IS-arkitekturen: Back Office Path

Habr förändrar världen. Vi har bloggat i över ett år. För ungefär ett halvår sedan fick vi ganska logisk feedback från invånare i Khabrovsk: "Dodo, du säger överallt att du har ditt eget system. Vad är detta för system? Och varför behöver pizzeriakedjan det?”

Vi satt och funderade och insåg att du har rätt. Vi försöker förklara allt med fingrarna, men det kommer ut i sönderrivna bitar och det finns ingen fullständig beskrivning av systemet någonstans. Så började en lång resa med att samla information, söka efter författare och skriva en serie artiklar om Dodo IS. Nu går vi!

Tack: Tack för att du delar din feedback med oss. Tack vare honom beskrev vi äntligen systemet, kompilerade en technoradar och kommer snart att rulla ut en stor beskrivning av våra processer. Utan er hade vi suttit så här i ytterligare 5 år.

Historia om Dodo IS-arkitekturen: Back Office Path

Artikelserie "Vad är Dodo IS?" kommer att berätta om:

  1. Tidig monolit i Dodo IS (2011-2015). (Pågående...)
  2. Backoffice-väg: separata baser och buss. (Du är här)
  3. Klientdelens väg: fasad ovanför basen (2016-2017). (Pågående...)
  4. Historien om riktiga mikrotjänster. (2018-2019). (Pågående...)
  5. Färdig skärning av monoliten och stabilisering av arkitekturen. (Pågående...)

Om du är intresserad av att lära dig något annat, skriv i kommentarerna.

Åsikt om den kronologiska beskrivningen från författaren
Jag håller regelbundet ett möte för nyanställda på temat "Systemarkitektur". Vi kallar det "Intro till Dodo IS Architecture" och det är en del av introduktionsprocessen för nya utvecklare. När jag i en eller annan form pratade om vår arkitektur, om dess egenskaper, utvecklade jag ett visst historiskt förhållningssätt till beskrivningen.

Traditionellt ser vi på ett system som en uppsättning komponenter (tekniska eller högre nivå), affärsmoduler som interagerar med varandra för att uppnå något mål. Och även om en sådan syn är motiverad för design, är den inte helt lämplig för beskrivning och förståelse. Det finns flera anledningar:

  • Verkligheten är annorlunda än den som finns på papper. Allt fungerar inte som planerat. Och vi är intresserade av hur allt faktiskt blev och fungerar.
  • Konsekvent presentation av information. Faktum är att du kan gå kronologiskt från början till nuvarande tillstånd.
  • Från enkelt till komplext. Inte universellt, men i vårt fall är det så. Arkitekturen gick från enklare tillvägagångssätt till mer komplexa. Ofta, genom komplikationer, problem med implementeringshastighet och stabilitet, såväl som dussintals andra egenskaper från listan över icke-funktionella krav (här väl omtalat om att kontrastera komplexitet med andra krav).

2011 såg Dodo IS-arkitekturen ut så här:

Historia om Dodo IS-arkitekturen: Back Office Path

År 2020 blev det lite mer komplicerat och blev så här:

Historia om Dodo IS-arkitekturen: Back Office Path

Hur gick denna utveckling till? Varför behövs olika delar av systemet? Vilka arkitektoniska beslut togs och varför? Låt oss ta reda på det i den här artikelserien.

De första problemen 2016: varför ska tjänster lämna monoliten?

De första artiklarna i serien kommer att handla om de tjänster som var de första att separera från monoliten. För att sätta in dig i ett sammanhang ska jag berätta vilka problem vi hade i systemet i början av 2016, att vi var tvungna att hantera separeringen av tjänster.

En enda MySql-databas i vilken alla applikationer som fanns vid den tiden i Dodo IS skrev sina register. Konsekvenserna blev:

  • Tung belastning (med 85 % av förfrågningarna läses).
  • Basen växte. På grund av detta blev kostnader och support ett problem.
  • En enda punkt av misslyckande. Om en applikation som skrev till databasen plötsligt började göra det mer aktivt, då kände andra applikationer effekten.
  • Ineffektivitet i lagring och frågor. Ofta lagrades data i någon struktur som var bekväm för vissa scenarier men inte för andra. Index påskyndar vissa operationer, men kan sakta ner andra.
  • En del av problemen löstes genom hastigt gjorda cacher och läs-repliker till databaser (detta kommer att diskuteras i en separat artikel), men de tillät oss bara att vinna tid och löste inte problemet i grunden.

Problemet var förekomsten av själva monoliten. Konsekvenserna blev:

  • Unika och sällsynta utgåvor.
  • Svårigheten ligger i att utveckla ett stort antal människor i samarbete.
  • Oförmåga att introducera ny teknik, nya ramverk och bibliotek.

Problem med basen och monoliten har beskrivits många gånger, till exempel i samband med krascher i början av 2018 (Var som Munch, eller några ord om teknisk skuld, Dagen Dodo IS slutade. Asynkront skript и Berättelsen om Dodo-fågeln från familjen Phoenix. Dodons stora fall ÄR), så jag ska inte dröja för mycket. Låt mig bara säga att vi ville ge mer flexibilitet när vi utvecklade tjänster. Först och främst gällde detta de som var mest laddade och rotade i hela systemet - Auth och Tracker.

Backoffice-väg: separata baser och buss

Kapitel Navigering

  1. Monolitens schema 2016
  2. Vi börjar ladda ur monoliten: separation av Auth och Tracker
  3. Vad gör Auth?
  4. Var kommer lasterna ifrån?
  5. Avlastning Auth
  6. Vad gör Tracker?
  7. Var kommer lasterna ifrån?
  8. Avlastning av Tracker

Monolitens schema 2016

Här är huvudblocken i 2016 Dodo IS-monoliten, och precis nedanför är en uppdelning av deras huvuduppgifter.
Historia om Dodo IS-arkitekturen: Back Office Path
Leverans kassa. Redovisning för kurirer, utfärdande av order till kurirer.
Kontaktcenter. Ta emot beställningar via operatören.
Plats. Våra webbplatser (dodopizza.ru, dodopizza.co.uk, dodopizza.by, etc.).
Auth. Auktoriserings- och autentiseringstjänst för backoffice.
tracker. Köksbeställningsspårare. Tjänst för att markera beredskapsstatus vid förberedelse av en beställning.
Restaurang kassa. Ta beställningar på en restaurang, kassagränssnitt.
Exportera. Ladda upp rapporter i 1C för redovisning.
Varningar och fakturor. Röstkommandon i köket (exempelvis ”Ny pizza har kommit”) + utskrift av fakturor för bud.
Shift Manager. Gränssnitt för en skiftchefs arbete: lista över beställningar, produktivitetsdiagram, föra anställda till skift.
Kontors chef. Gränssnitt för franchisetagares och chefers arbete: mottagande av anställda, rapporter om pizzerians arbete.
Restaurang styrelse. Visar menyer på TV-apparater på pizzerior.
Administration. Inställningar för en specifik pizzeria: meny, priser, bokföring, kampanjkoder, kampanjer, banners för sajten, etc.
Personalkonto. Anställdas arbetsscheman, information om anställda.
Motivationstavla för kök. En separat skärm som hänger i köket och visar pizzakokarnas hastighet.
Kommunikation. Skickar sms och mail.
Fillagring. Egen tjänst för att ta emot och utfärda statiska filer.

De första försöken att lösa problem hjälpte oss, men de var bara ett tillfälligt andrum. De blev inga systemlösningar, så det var klart att något måste göras med baserna. Dela till exempel upp den allmänna databasen i flera mer specialiserade.

Vi börjar ladda ur monoliten: separation av Auth och Tracker

De viktigaste tjänsterna som sedan skrev och läste från databasen mer än andra:

  1. Auth. Auktoriserings- och autentiseringstjänst för backoffice.
  2. Spårare. Köksbeställningsspårare. Tjänst för att markera beredskapsstatus vid förberedelse av en beställning.

Vad gör Auth?

Auth är en tjänst genom vilken användare loggar in på backoffice (det finns en separat oberoende inloggning på klientsidan). Det hänvisas också till i begäran för att säkerställa att rätt åtkomsträttigheter finns och att dessa rättigheter inte har ändrats sedan senaste inloggningen. Enheter går in på pizzerior genom den.

Vi vill till exempel öppna en display med status för genomförda beställningar på TV:n som hänger i hallen. Sedan öppnar vi auth.dodopizza.ru, välj "Logga in som enhet", en kod visas som kan anges på en speciell sida på skiftchefens dator, som anger typen av enhet (enhet). TV:n själv kommer att gå till det önskade gränssnittet för sin pizzeria och börja visa där namnen på kunder vars beställningar är klara.

Historia om Dodo IS-arkitekturen: Back Office Path

Var kommer lasterna ifrån?

Varje inloggad backoffice-användare går till databasen för varje begäran, till användartabellen, drar ut användaren därifrån genom en sql-fråga och kontrollerar om han har nödvändig åtkomst och rättigheter till denna sida.

Var och en av enheterna gör samma sak endast med enhetstabellen och kontrollerar dess roll och åtkomster. Ett stort antal förfrågningar till huvuddatabasen leder till dess laddning och slöseri med allmänna databasresurser på dessa operationer.

Avlastning Auth

Auth har en isolerad domän, det vill säga data om användare, inloggningar eller enheter kommer in i tjänsten (för närvarande framtida) och förblir där. Om någon behöver dem kommer han att gå till denna tjänst för data.

VAR. Arbetsflödet var initialt så här:

Historia om Dodo IS-arkitekturen: Back Office Path

Jag skulle vilja förklara lite hur det fungerade:

  1. En extern begäran kommer till backend (Asp.Net MVC där), och tar med sig en sessionscookie, som används för att hämta sessionsdata från Redis(1). Den innehåller antingen information om åtkomster och sedan är åtkomsten till styrenheten öppen (3,4), eller inte.
  2. Om det inte finns någon åtkomst måste du gå igenom auktoriseringsproceduren. Här visas den för enkelhets skull som en del av sökvägen i samma attribut, även om detta är en övergång till inloggningssidan. I fallet med ett positivt scenario kommer vi att få en korrekt ifylld session och gå till Backoffice Controller.
  3. Om det finns data måste du kontrollera det för relevans i användardatabasen. Har hans roll förändrats, borde han inte få komma in på sidan nu? I det här fallet, efter att ha tagit emot sessionen (1), måste du gå direkt till databasen och kontrollera användarens åtkomst med hjälp av autentiseringslogikskiktet (2). Gå sedan antingen till inloggningssidan eller gå till kontrollern. Detta är ett enkelt system, men inte helt standard.
  4. Om alla procedurer är slutförda hoppar vi vidare i logiken i kontroller och metoder.

Användardata separeras från all annan data, den lagras i en separat medlemstabell, funktioner från AuthService-logikskiktet kan mycket väl bli API-metoder. Domänens gränser är ganska tydligt definierade: användare, deras roller, åtkomstdata, utfärdande och återkallande av åtkomst. Allt ser ut att kunna flyttas till en separat tjänst.

BLEV. Det är vad de gjorde:

Historia om Dodo IS-arkitekturen: Back Office Path

Detta tillvägagångssätt har ett antal problem. Att till exempel anropa en metod i en process är inte detsamma som att anropa en extern tjänst via http. Latens, tillförlitlighet, stödbarhet och transparens för operationen är helt annorlunda. Andrey Morevsky talade mer detaljerat om exakt dessa problem i sin rapport "50 nyanser av mikrotjänster".

Autentiseringstjänsten och med den enhetstjänsten används för backoffice, det vill säga för tjänster och gränssnitt som används i produktionen. Autentisering för klienttjänster (som en webbplats eller mobilapplikation) sker separat utan att använda Auth. Separationen tog ungefär ett år, och nu arbetar vi igen med detta ämne och överför systemet till nya autentiseringstjänster (med standardprotokoll).

Varför tog separationen så lång tid?
Det var många problem längs vägen som saktade ner oss:

  1. Vi ville överföra data om användare, enheter och autentisering från landsdatabaser till en. För att göra detta var vi tvungna att överföra alla tabeller och användning från int-identifieraren till den globala UUId-identifieraren (vi har nyligen omarbetat den här koden Roman Bukin "Uuid - den stora historien om en liten struktur" och öppen källkodsprojekt Primitiver). Lagring av användardata (eftersom detta är personlig information) har sina begränsningar och för vissa länder är det nödvändigt att lagra dem separat. Men det måste finnas ett globalt användar-ID.
  2. Många tabeller i databasen har granskningsinformation om användaren som utförde operationen. Detta krävde ytterligare en mekanism för att säkerställa konsekvens.
  3. Efter skapandet av API-tjänster blev det en lång och gradvis överföring till ett annat system. Växlingarna måste ske sömlöst för användarna och krävde manuellt arbete.

Schema för att registrera en enhet i en pizzeria:

Historia om Dodo IS-arkitekturen: Back Office Path

Allmän arkitektur efter separering av Auth- och Devices-tjänsten:

Historia om Dodo IS-arkitekturen: Back Office Path

Notera. För 2020 arbetar vi på en ny version av Auth, som är baserad på auktoriseringsstandarden OAuth 2.0. Denna standard är ganska komplex, men användbar för att utveckla en end-to-end-autentiseringstjänst. I artikeln "Subtiliteter av auktorisering: översikt över OAuth 2.0-teknik» vi Alexey Chernyaev försökte prata om standarden så enkelt och tydligt som möjligt så att du sparar tid på att studera den.

Vad gör Tracker?

Nu om den andra av de laddade tjänsterna. Spåraren har en dubbel roll:

  • Dels är dess uppgift att visa de anställda i köket vilka beställningar som är på gång, vilka produkter som behöver förberedas nu.
  • Digitalisera däremot alla processer i köket.

Historia om Dodo IS-arkitekturen: Back Office Path

När en ny produkt (till exempel pizza) dyker upp i en beställning, går den till spårningsstationen "Rolling". På den här stationen finns det en pizzamakare som tar en bulle av önskad storlek och rullar ut den, varefter han markerar på spårningstabletten att han har slutfört sin uppgift och skickar den utkavlade degbasen till nästa station - "Fyllning" .

Där toppar nästa pizzamakare pizzan, markerar sedan på surfplattan att han har slutfört sin uppgift och sätter in pizzan i ugnen (detta är också en separat station som måste markeras på surfplattan). Ett sådant system fanns från första början i Dodo och från början av Dodo IS. Det låter dig helt spåra och digitalisera alla operationer. Dessutom föreslår spåraren hur man förbereder en viss produkt, utför varje typ av produkt enligt sina egna tillverkningsscheman, lagrar den optimala tillagningstiden för produkten och spårar alla operationer på produkten.

Historia om Dodo IS-arkitekturen: Back Office PathSå här ser surfplattans skärm ut på spårningsstationen Raskatka.

Var kommer lasterna ifrån?

Varje pizzeria har cirka fem tabletter med en tracker. Under 2016 hade vi mer än 100 pizzerior (och nu finns det fler än 600). Var och en av surfplattorna gör en förfrågan till backend var 10:e sekund och samlar in data från beställningstabellen (länk till klienten och adress), beställningssammansättningen (länk till produkten och angivande av kvantitet) och motivationstabellen (den spårar tidpunkten för tryckning). När en pizzatillverkare klickar på en produkt på spåraren uppdateras posterna i alla dessa tabeller. Beställningstabellen är generell, den innehåller samtidigt infogningar när man tar emot en beställning, uppdateringar från andra delar av systemet och många avläsningar, till exempel på en TV som hänger i en pizzeria och visar färdiga beställningar för kunder.

Under perioden av kamp med belastningar, när allt och alla cachades och överfördes till en asynkron replika av databasen, fortsatte dessa operationer med spåraren att gå till huvuddatabasen. Det ska inte finnas någon fördröjning här, informationen måste vara uppdaterad, osynkroniserad är oacceptabelt.

Dessutom tillät inte bristen på våra egna tabeller och index på dem oss att skriva mer specifika frågor skräddarsydda för vår användning. Det kan till exempel vara effektivt för en spårare att ha ett index för en pizzeria på sin beställningstabell. Vi skrapar alltid pizzeriabeställningar från trackerdatabasen. Samtidigt, för att acceptera en beställning, är det inte så viktigt vilken pizzeria den hamnar i, det som är viktigare är vilken kund som gjort denna beställning. Det betyder att det måste finnas ett index på klienten. Det är inte heller nödvändigt för spåraren att lagra id:t för det utskrivna kvittot eller bonuskampanjer som är kopplade till beställningen i beställningstabellen. Vår spårningstjänst är inte intresserad av denna information. I en gemensam monolitisk databas kan tabeller bara vara en kompromiss mellan alla användare. Detta var ett av de ursprungliga problemen.

VAR. Till en början var arkitekturen så här:

Historia om Dodo IS-arkitekturen: Back Office Path

Även efter att ha separerats i separata processer förblev det mesta av kodbasen gemensam för olika tjänster. Allt under kontrollerna var enat och bodde i ett förråd. Vanliga metoder för tjänster, arkiv och en gemensam databas som innehåller vanliga tabeller användes.

Avlastning av Tracker

Det största problemet med trackern är att data måste synkroniseras mellan olika databaser. Detta är också dess huvudsakliga skillnad från uppdelningen av Auth-tjänsten; ordningen och dess status kan ändras och bör visas i olika tjänster.

Vi tar emot beställningar i restaurangkassan (detta är en tjänst), den lagras i databasen i statusen "Accepterad". Efter det bör den gå till spåraren, där den kommer att ändra sin status flera gånger: från "Kök" till "Packad". I det här fallet kan vissa yttre påverkan från Kassören eller Shift Manager-gränssnittet inträffa med beställningen. Jag kommer att ge orderstatus med deras beskrivningar i tabellen:

Historia om Dodo IS-arkitekturen: Back Office Path
Orderstatusändringsschemat ser ut så här:

Historia om Dodo IS-arkitekturen: Back Office Path

Statusen ändras mellan olika system. Och här är spåraren inte det slutgiltiga systemet där datan är låst. Vi har sett flera möjliga tillvägagångssätt för separation i ett sådant fall:

  1. Vi koncentrerar alla beställningsåtgärder i en tjänst. I vårt fall kräver detta alternativ för mycket service för att behandla beställningen. Om vi ​​hade slutat där hade vi slutat med en andra monolit. Vi skulle inte ha löst problemen.
  2. Ett system ringer till ett annat. Det andra alternativet är mer intressant. Men med det är samtalskedjor möjliga (kaskadfel), är komponenternas anslutningsbarhet högre och det är svårare att hantera.
  3. Vi anordnar evenemang och varje tjänst utbyter med varandra genom dessa evenemang. Som ett resultat valdes det tredje alternativet, enligt vilket alla tjänster börjar utbyta händelser med varandra.

Att vi valde det tredje alternativet innebar att trackern skulle ha en egen databas och för varje ändring i ordningen skickade den ett event om detta, som andra tjänster skulle prenumerera på och som också skulle ingå i masterdatabasen. För att göra detta behövde vi någon tjänst som skulle säkerställa leverans av meddelanden mellan tjänsterna.

Vid den tiden hade vi redan RabbitMQ i stacken, därav det slutliga beslutet att använda det som en meddelandeförmedlare. Diagrammet visar övergången av en beställning från restaurangkassörskan till spåraren, där den ändrar dess status och dess visning på chefens beställningsgränssnitt. BLI:

Historia om Dodo IS-arkitekturen: Back Office Path

Beställ väg steg för steg
Beställningsvägen börjar vid en av beställningskälltjänsterna. Här är restaurangkassörskan:

  1. Beställningen är helt klar i kassan och det är dags att skicka den till spåraren. Händelsen som spåraren är prenumererad på kastas.
  2. Trackern, som accepterar en beställning, sparar den i sin egen databas, gör händelsen "Order Accepted by Tracker" och skickar den till RMQ.
  3. Flera hanterare är redan prenumererade på den anpassade händelsebussen. För oss är den som synkroniserar med den monolitiska databasen viktig.
  4. Hanteraren tar emot händelsen, väljer från den de data som är viktiga för den: i vårt fall är detta orderstatusen "Accepted by Tracker" och uppdaterar sin orderenhet i huvuddatabasen.

Om någon behöver en beställning specifikt från den monolitiska beställningstabellen, kan de läsa den därifrån också. Det här är till exempel vad ordergränssnittet i Shift Manager behöver:

Historia om Dodo IS-arkitekturen: Back Office Path

Alla andra tjänster kan också prenumerera på beställningsevenemang från trackern för att kunna använda dem själva.

Om en order efter en tid tas i produktion ändras dess status först i dess databas (Tracker-databasen), och sedan genereras "OrderInWork"-händelsen omedelbart. Den kommer också in i RMQ, varifrån den synkroniseras i en monolitisk databas och levereras till andra tjänster. Det kan finnas olika problem längs denna väg; mer information om dem finns i Zhenya Peshkovs rapport om implementeringsdetaljerna för Eventual Consistency in Tracker.

Slutlig arkitektur efter ändringar i Auth och Tracker

Historia om Dodo IS-arkitekturen: Back Office Path

För att sammanfatta: Från början hade jag idén att paketera Dodo IS-systemets nioåriga historia i en artikel. Jag ville snabbt och enkelt prata om evolutionens stadier. Men efter att ha satt mig ner för att studera materialet insåg jag att allt är mycket mer komplext och intressant än det verkar.

När jag reflekterade över fördelarna (eller bristen på sådana) med sådant material, kom jag till slutsatsen att kontinuerlig utveckling är omöjlig utan fullfjädrade krönikor av händelser, detaljerade återblickar och analys av ens tidigare beslut.

Jag hoppas att du tyckte att det var användbart och intressant att lära dig om vår resa. Nu står jag inför ett val av vilken del av Dodo IS-systemet jag ska beskriva i nästa artikel: skriv i kommentarerna eller rösta.

Endast registrerade användare kan delta i undersökningen. Logga in, Snälla du.

Vilken del av Dodo IS skulle du vilja lära dig om i nästa artikel?

  • 24,1%Tidig monolit i Dodo IS (2011-2015)14

  • 24,1%Första problemen och deras lösningar (2015-2016)14

  • 20,7%Byggnadsdelens väg: fasad ovanför basen (2016-2017)12

  • 36,2%Historia om riktiga mikrotjänster (2018-2019)21

  • 44,8%Avslutad skärning av monoliten och stabilisering av arkitekturen26

  • 29,3%Om ytterligare planer för utvecklingen av systemet17

  • 19,0%Jag vill inte veta något om Dodo IS11

58 användare röstade. 6 användare avstod från att rösta.

Källa: will.com

Lägg en kommentar