Byggstenar för distribuerade applikationer. Noll approximation

Byggstenar för distribuerade applikationer. Noll approximation

Världen står inte stilla. Framsteg skapar nya tekniska utmaningar. I enlighet med förändrade krav måste arkitekturen för informationssystem utvecklas. Idag kommer vi att prata om händelsedriven arkitektur, samtidighet, samtidighet, asynkroni, och hur du kan leva fredligt med allt detta i Erlang.

Inledning

Beroende på storleken på det designade systemet och kraven på det väljer vi, utvecklarna, metoden för att utbyta information i systemet. I de flesta fall, för att organisera interaktionen mellan tjänster, kan ett fungerande alternativ vara ett system med en mäklare, till exempel baserat på RabbitMQ eller kafka. Men ibland är flödet av händelser, SLA och kontrollnivån över systemet sådana att färdiga meddelanden inte passar oss. Självklart kan man komplicera systemet lite genom att ta ansvar för transportlagret och klusterbildningen, till exempel med ZeroMQ eller nanomsg. Men om systemet har tillräckligt med genomströmning och kapacitet för ett standard Erlang-kluster, kräver frågan om att införa en ytterligare enhet detaljerad studie och ekonomisk motivering.

Ämnet reaktiva distribuerade applikationer är ganska brett. För att hålla sig inom artikelns format kommer ämnet för dagens diskussion endast att vara homogena miljöer byggda på Erlang/Elixir. Erlang/OTP-ekosystemet låter dig implementera en reaktiv arkitektur med minsta möjliga ansträngning. Men i alla fall kommer vi att behöva ett meddelandelager.

Teoretisk grund

Design börjar med att definiera mål och begränsningar. Huvudmålet är inte inom utvecklingsområdet för utvecklingens skull. Vi måste skaffa ett säkert och skalbart verktyg på grundval av vilket vi kan skapa och, viktigast av allt, utveckla moderna applikationer på olika nivåer: med utgångspunkt från enserverapplikationer som betjänar en liten publik, som senare kan utvecklas till kluster på upp till 50 -60 noder, slutar med klusterfederationer. Det huvudsakliga målet är alltså att maximera vinsten genom att minska kostnaderna för utveckling och ägande av det slutliga systemet.

Låt oss lyfta fram fyra huvudkrav för det slutliga systemet:

  • Сhändelseorienterad.
    Systemet är alltid redo att passera genom flödet av händelser och utföra nödvändiga åtgärder;
  • Мskalbarhet.
    Enskilda block kan skalas både vertikalt och horisontellt. Hela systemet måste vara kapabelt till oändlig horisontell tillväxt;
  • Оfeltolerans.
    Alla nivåer och alla tjänster ska kunna återhämta sig automatiskt från fel;
  • Гgaranterad svarstid.
    Tid är värdefull och användare bör inte vänta för länge.

Kommer du ihåg den gamla sagan om "Den lilla motorn som kunde"? För att det designade systemet framgångsrikt ska lämna prototypstadiet och vara progressivt måste dess grund uppfylla minimikraven SMOG.

Ytterligare en punkt läggs till meddelandehantering som ett infrastrukturverktyg och grunden för alla tjänster: användarvänlighet för programmerare.

Eventorienterad

För att en applikation ska växa från en enskild server till ett kluster måste dess arkitektur stödja lös koppling. Den asynkrona modellen uppfyller detta krav. I den bryr sig avsändaren och mottagaren om informationsbelastningen i meddelandet och oroar sig inte för överföring och routing inom systemet.

Skalbarhet

Skalbarhet och systemeffektivitet ligger bredvid varandra. Applikationskomponenter måste kunna utnyttja alla tillgängliga resurser. Ju mer effektivt vi kan utnyttja kapaciteten och ju mer optimala våra bearbetningsmetoder, desto mindre pengar lägger vi på utrustning.

Inom en enda maskin skapar Erlang en mycket konkurrenskraftig miljö. Balansen mellan samtidighet och parallellitet kan ställas in genom att välja antalet operativsystemtrådar som är tillgängliga för Erlang VM och antalet schemaläggare som använder dessa trådar.
Erlang-processer delar inte tillstånd och fungerar i icke-blockerande läge. Detta ger relativt låg latens och högre genomströmning än traditionella blockeringsbaserade applikationer. Erlangs schemaläggare säkerställer rättvis allokering av CPU och IO, och frånvaron av blockering gör att applikationen kan svara även under toppbelastningar eller fel.

På klusternivå finns också problemet med bortskaffande. Det är viktigt att alla maskiner i klustret är jämnt belastade och att nätverket inte överbelastas. Låt oss föreställa oss en situation: användartrafik landar på inkommande balanserare (haproxy, nginx, etc), de fördelar bearbetningsförfrågningar så jämnt som möjligt mellan uppsättningen tillgängliga backends. Inom applikationsinfrastrukturen är tjänsten som implementerar det nödvändiga gränssnittet bara den sista milen och kommer att behöva begära ett antal andra tjänster för att svara på den initiala begäran. Interna förfrågningar kräver också routing och balansering.
För att effektivt hantera dataflöden måste meddelandehantering ge utvecklare ett gränssnitt för att hantera routing och lastbalansering. Tack vare detta kommer utvecklare att kunna, med hjälp av mikrotjänstmönster (aggregator, proxy, kedja, filial, etc), lösa både standardproblem och de som sällan uppstår.

Ur affärsmässig synvinkel är skalbarhet ett av riskhanteringsverktygen. Det viktigaste är att tillfredsställa kundernas önskemål genom att använda utrustningen optimalt:

  • När utrustningens kraft ökar som ett resultat av framsteg. Den kommer inte att vara inaktiv på grund av ofullkomlig programvara. Erlang skalar vertikalt bra och kommer alltid att kunna utnyttja alla CPU-kärnor och tillgängligt minne;
  • I molnmiljöer kan vi hantera mängden utrustning beroende på aktuell eller förutspådd belastning och garantera SLA.

feltolerans

Låt oss överväga två axiom: "Mislyckanden är oacceptabla" och "Det kommer alltid att finnas misslyckanden." För ett företag innebär mjukvarufel förlust av pengar, och vad värre är, förlust av rykte. Genom att balansera mellan eventuella förluster och kostnaden för att utveckla feltolerant programvara kan man ofta hitta en kompromiss.

På kort sikt sparar en arkitektur som innehåller feltolerans pengar på att köpa färdiga klustringslösningar. De är dyra och de har också buggar.
På lång sikt betalar en feltålig arkitektur sig själv många gånger i alla utvecklingsstadier.
Meddelanden i kodbasen gör att du i detalj kan räkna ut samspelet mellan komponenter i systemet i utvecklingsstadiet. Detta förenklar uppgiften att svara och hantera fel, eftersom alla kritiska komponenter hanterar fel, och det resulterande systemet vet hur det automatiskt återgår till det normala efter ett designfel.

Lyhördhet

Oavsett misslyckanden måste applikationen svara på förfrågningar och uppfylla SLA. Verkligheten är att människor inte vill vänta, så företag måste anpassa sig därefter. Fler och fler ansökningar förväntas vara mycket lyhörda.
Responsiva applikationer fungerar nästan i realtid. Erlang VM arbetar i mjukt realtidsläge. För vissa områden, som aktiehandel, medicin och kontroll av industriell utrustning, är hårt realtidsläge viktigt.
Responsiva system förbättrar UX och gynnar verksamheten.

Preliminär sammanfattning

När jag planerade den här artikeln ville jag dela med mig av min erfarenhet av att skapa en meddelandemäklare och bygga komplexa system baserade på den. Men den teoretiska och motiverande delen visade sig vara ganska omfattande.
I den andra delen av artikeln kommer jag att prata om nyanserna av att implementera utbytespunkter, meddelandemönster och deras tillämpning.
I den tredje delen kommer vi att behandla allmänna frågor om organisering av tjänster, routing och balansering. Låt oss prata om den praktiska sidan av skalbarhet och feltolerans hos system.

Slutet på första delen.

Photo Shoot @lucabravo.

Källa: will.com

Lägg en kommentar