Programvaruarkitektur och systemdesign: The Big Picture and Resource Guide

Hallå kollegor.

Idag erbjuder vi dig en översättning av en artikel av Tugberk Ugurlu, som åtog sig att i en relativt liten volym beskriva principerna för att designa moderna mjukvarusystem. Här är vad författaren säger om sig själv i sammanfattning:

Programvaruarkitektur och systemdesign: The Big Picture and Resource Guide
Eftersom det är absolut omöjligt att i en habro-artikel täcka ett så kolossalt ämne som arkitektoniska mönster + designmönster från och med 2019, rekommenderar vi inte bara texten av Mr. Uruglu själv, utan också de många länkar som han vänligen inkluderade i den. Om du gillar det kommer vi att publicera en mer högspecialiserad text om utformningen av distribuerade system.

Programvaruarkitektur och systemdesign: The Big Picture and Resource Guide

snapshot Isaac Smith från Unsplash

Om du aldrig har behövt möta sådana utmaningar som att designa ett mjukvarusystem från grunden, då är det ibland inte ens klart var du ska börja när du påbörjar ett sådant arbete. Jag tror att du först måste dra gränser så att du har en mer eller mindre säker uppfattning om exakt vad du ska designa, och sedan kavla upp ärmarna och arbeta inom dessa gränser. Som utgångspunkt kan du ta en produkt eller tjänst (helst en som du verkligen gillar) och lista ut hur du ska implementera den. Du kan bli förvånad över hur enkel den här produkten ser ut och hur mycket komplex den faktiskt innehåller. Glöm inte: enkel - oftast komplex, och det är okej.

Jag tror att det bästa rådet jag kan ge till alla som börjar designa ett system är detta: gör inga antaganden! Redan från början måste du specificera de fakta som är kända om detta system och förväntningarna i samband med det. Här är några bra frågor att ställa för att hjälpa dig komma igång med din design:

  • Vad är problemet vi försöker lösa?
  • Vad är det högsta antalet användare som kommer att interagera med vårt system?
  • Vilka mönster för att skriva och läsa data kommer vi att använda?
  • Vilka är de förväntade misslyckandefallen, hur ska vi hantera dem?
  • Vilka är förväntningarna på systemkonsistens och tillgänglighet?
  • Måste du ta hänsyn till eventuella krav relaterade till extern verifiering och reglering när du arbetar?
  • Vilka typer av känslig information kommer vi att lagra?

Det här är bara några frågor som har varit användbara för både mig och de team som jag har deltagit i under årens yrkesverksamhet. Om du känner till svaren på dessa frågor (och alla andra som är relevanta för det sammanhang där du måste arbeta), så kan du gradvis fördjupa dig i de tekniska detaljerna i problemet.

Ställ in den initiala nivån

Vad menar jag med "baslinje" här? Faktiskt, i vår tid kan de flesta problem inom mjukvaruindustrin "lösas" med hjälp av befintliga metoder och teknologier. Genom att navigera i detta landskap får du följaktligen ett visst försprång när du ställs inför problem som någon annan måste lösa före dig. Glöm inte att program är skrivna för att lösa affärs- och användarproblem, så vi strävar efter att lösa problemet på det mest raka och enkla (ur användarens synvinkel) sätt. Varför är detta viktigt att komma ihåg? Kanske i ditt koordinatsystem gillar du att leta efter unika lösningar för alla problem, eftersom du tänker, "vad är jag för programmerare om jag följer mönster överallt"? Faktiskt, konsten här är att fatta beslut om var och vad man ska göra. Naturligtvis måste var och en av oss ta itu med unika problem då och då, som var och en är en riktig utmaning. Men om vår initiala nivå är tydligt definierad, då vet vi vad vi ska lägga vår energi på: att söka efter färdiga alternativ för att lösa det problem som vi har framför oss, eller studera det ytterligare och få en djupare förståelse.

Jag tror att jag kunde övertyga dig om att om en specialist självsäkert förstår vad den arkitektoniska komponenten i några underbara mjukvarusystem är, så kommer denna kunskap att vara oumbärlig för att behärska en arkitekts konst och utveckla en solid grund inom detta område.

Okej, så var ska man börja? U Donna Martina Det finns ett arkiv på GitHub som heter system-design-primer, där du kan lära dig att designa storskaliga system, samt förbereda dig för intervjuer om detta ämne. Förvaret har en sektion med exempel riktiga arkitekturer, där det särskilt övervägs hur de närmar sig designen av sina system några välkända företagt.ex. Twitter, Uber, etc.

Men innan vi går vidare till detta material, låt oss ta en närmare titt på de viktigaste arkitektoniska utmaningarna som vi står inför i praktiken. Detta är viktigt eftersom man måste specificera MÅNGA aspekter av ett envist och mångfacetterat problem, och sedan lösa det inom ramen för de regelverk som gäller i ett givet system. Jackson Gabbard, skrev en tidigare Facebook-anställd 50 minuters video om systemdesignintervjuer, där han delade med sig av sin egen erfarenhet av screening av hundratals sökande. Även om videon fokuserar mycket på design av stora system och de framgångskriterier som är viktiga när man letar efter en kandidat för en sådan position, kommer den fortfarande att fungera som en omfattande resurs för vad som är viktigast när man designar system. Jag föreslår också sammanfattning den här videon.

Bygg kunskap om att lagra och hämta data

Vanligtvis har ditt beslut om hur du lagrar och hämtar din data på lång sikt en kritisk inverkan på systemets prestanda. Därför måste du först förstå de förväntade skriv- och läsegenskaperna hos ditt system. Då behöver du kunna utvärdera dessa indikatorer och göra val utifrån de bedömningar som gjorts. Du kan dock effektivt hantera detta arbete endast om du förstår befintliga datalagringsmönster. I princip innebär detta gedigen kunskap relaterad till databasval.

Databaser kan ses som datastrukturer som är extremt skalbara och hållbara. Därför bör kunskap om datastrukturer vara mycket användbar för dig när du väljer en viss databas. Till exempel, Redis är en datastrukturserver som stöder olika typer av värden. Den låter dig arbeta med datastrukturer som listor och uppsättningar och läsa data med välkända algoritmer, till exempel, LRU, organisera sådant arbete i en hållbar och mycket tillgänglig stil.

Programvaruarkitektur och systemdesign: The Big Picture and Resource Guide

snapshot Samuel Zeller från Unsplash

När du har en tillräcklig förståelse för de olika datalagringsmönstren, gå vidare till att studera datakonsistens och tillgänglighet. Först och främst måste du förstå CAP-sats åtminstone i allmänna termer, och sedan polera denna kunskap genom att titta närmare på etablerade mönster konsistens и tillgänglighet. På så sätt kommer du att utveckla en förståelse för området och förstå att läsning och skrivning av data faktiskt är två väldigt olika problem, var och en med sina egna unika utmaningar. Med några få konsistens- och tillgänglighetsmönster kan du avsevärt öka systemets prestanda samtidigt som du säkerställer ett smidigt dataflöde till dina applikationer.

Slutligen, för att avsluta samtalet om datalagringsproblem, bör vi också nämna cachning. Ska det köras samtidigt på klienten och servern? Vilken data kommer att finnas i din cache? Och varför? Hur organiserar du cache-ogiltigförklaring? Kommer det att göras regelbundet, med vissa intervall? Om ja, hur ofta? Jag rekommenderar att börja studera dessa ämnen med nästa avsnitt ovannämnda systemdesignprimer.

Kommunikationsmönster

System består av olika komponenter; dessa kan vara olika processer som körs inom samma fysiska nod, eller olika maskiner som körs på olika delar av ditt nätverk. Vissa av dessa resurser inom ditt nätverk kan vara privata, men andra bör vara offentliga och öppna för konsumenter som kan komma åt dem utifrån.

Det är nödvändigt att säkerställa kommunikationen av dessa resurser med varandra, liksom utbytet av information mellan hela systemet och omvärlden. När det gäller systemdesign står vi här igen inför en rad nya och unika utmaningar. Låt oss se hur de kan vara användbara asynkrona uppgiftsflöden, och vad sidEn mängd olika kommunikationsmönster finns tillgängliga.

Programvaruarkitektur och systemdesign: The Big Picture and Resource Guide

snapshot Tony Stoddard från Unsplash

När man organiserar kommunikationen med omvärlden är det alltid väldigt viktigt säkerhet, vars tillhandahållande också måste tas på allvar och aktivt eftersträvas.

Anslutningsfördelning

Jag är inte säker på att det kommer att verka motiverat för alla att lägga detta ämne i ett separat avsnitt. Ändå kommer jag att presentera detta koncept i detalj här, och jag tror att materialet i detta avsnitt bäst beskrivs med termen "anslutningsdistribution".

System bildas genom att korrekt ansluta många komponenter, och deras kommunikation med varandra är ofta organiserad på basis av etablerade protokoll, till exempel TCP och UDP. Dessa protokoll som sådana är dock ofta otillräckliga för att möta alla behov hos moderna system, som ofta drivs under hög belastning och dessutom är mycket beroende av användarbehov. Det är ofta nödvändigt att hitta sätt att fördela anslutningar för att klara så höga belastningar på systemet.

Denna fördelning är baserad på det välkända domännamnssystem (DNS). Ett sådant system tillåter domännamnstransformationer såsom viktad round robin och latensbaserade metoder för att hjälpa till att fördela belastningen.

Lastbalansering är fundamentalt viktigt, och praktiskt taget alla stora internetsystem vi har att göra med idag finns bakom en eller flera lastbalanserare. Lastbalanserare hjälper till att distribuera klientförfrågningar över flera tillgängliga instanser. Belastningsutjämnare finns i både hårdvara och mjukvara, men i praktiken måste du oftare ta itu med mjukvara, t.ex. haproxy и ELB. Omvända proxyservrar konceptuellt också väldigt lik lastbalanserare, även om det finns ett intervall mellan ettan och tvåan tydliga skillnader. Dessa skillnader måste man ta hänsyn till när man utformar ett system utifrån dina behov.

Du bör också veta om innehållsleveransnätverk (CDN). Ett CDN är ett globalt distribuerat nätverk av proxyservrar som levererar information från noder som är geografiskt belägna närmare en specifik användare. CDN är att föredra att använda om du arbetar med statiska filer skrivna i JavaScript, CSS och HTML. Dessutom är molntjänster som tillhandahåller trafikhanterare vanliga idag, t.ex. Azure Traffic Manager, vilket ger dig global distribution och minskad latens när du arbetar med dynamiskt innehåll. Sådana tjänster är dock vanligtvis användbara i de fall du måste arbeta med statslösa webbtjänster.

Låt oss prata om affärslogik. Strukturera affärslogik, uppgiftsflöden och komponenter

Så vi lyckades diskutera olika infrastrukturella aspekter av systemet. Troligtvis tänker användaren inte ens på alla dessa delar av ditt system och bryr sig ärligt talat inte om dem alls. Användaren är intresserad av hur det är att interagera med ditt system, vad som kan uppnås genom att göra detta, och även hur systemet utför användarkommandon, vad och hur det gör med användardata.

Som titeln på den här artikeln antyder, tänkte jag prata om mjukvaruarkitektur och systemdesign. Följaktligen planerade jag inte att täcka mjukvarudesignmönster som beskriver hur mjukvarukomponenter skapas. Men ju mer jag tänker på det, desto mer verkar det för mig som att gränsen mellan mjukvarudesignmönster och arkitektoniska mönster är mycket suddig, och de två begreppen är nära besläktade. Låt oss ta till exempel evenemangsregistrering (händelsekälla). När du väl anammat det här arkitektoniska mönstret kommer det att påverka nästan alla aspekter av ditt system: långtidslagring av data, nivån av konsistens som används i ditt system, formen på komponenterna i det, etc., etc. Därför bestämde jag mig för att nämna några arkitektoniska mönster som direkt relaterar till affärslogik. Även om den här artikeln måste begränsa sig till en enkel lista, uppmuntrar jag dig att bekanta dig med den och fundera över idéerna som är förknippade med dessa mönster. Varsågod:

Samarbetssätt

Det är extremt osannolikt att du kommer att befinna dig i ett projekt som den deltagare som är ensam ansvarig för systemdesignprocessen. Tvärtom kommer du med största sannolikhet att interagera med kollegor som arbetar både inom och utanför din uppgift. I det här fallet kan du behöva utvärdera de utvalda tekniska lösningarna med kollegor, identifiera affärsbehov och förstå hur man bäst parallelliserar uppgifter.

Programvaruarkitektur och systemdesign: The Big Picture and Resource Guide

snapshot Kaleidico från Unsplash

Det första steget är att utveckla en korrekt och delad förståelse för vad affärsmålet du försöker uppnå är och vilka rörliga delar du måste hantera. Gruppmodelleringstekniker, i synnerhet stormande händelser (event storming) hjälper till att avsevärt påskynda denna process och öka dina chanser att lyckas. Detta arbete kan göras före eller efter att du skisserar gränserna för dina tjänster, och sedan fördjupa den när produkten mognar. Baserat på graden av konsekvens som kommer att uppnås här kan du också formulera vanligt språk för det begränsade sammanhang du arbetar i. När du behöver prata om arkitekturen för ditt system kan du ha nytta av det modell C4, föreslagna Simon Brown, speciellt när du behöver förstå hur mycket du måste gå in på detaljerna i problemet, visualisera de saker du vill kommunicera.

Det finns förmodligen en annan mogen teknologi i detta ämne som inte är mindre användbar än Domain Driven Design. Däremot återgår vi på något sätt till att förstå ämnesområdet, så kunskap och erfarenhet inom området Domändriven design bör vara användbar för dig.

Källa: will.com

Lägg en kommentar