Distribuerede systemer: Hvornår du skal bygge dem, og hvordan man skalerer. En trin-for-trin guide.

Det slår mig altid, hvor mange juniorudviklere, der lider af bedrageresyndrom, da de begyndte at skabe deres produkt.

Jeg får det, er der mange mind-blowing eksempler på top virksomheder med utroligt komplekse distribuerede systemer, der kan håndtere milliarder af anmodninger , yndefuldt opgradere hundredvis af applikationer uden nogen nedetid, komme sig katastrofe i sekunder, slipper hver 60 minutter, og har lys hastighed svartider fra hvor som helst i verden.

Disse forventninger kan være ret overvældende, når du starter dit projekt. Men som mange af jer allerede ved, er et flertal af disse virksomheder startet med et minimalt levedygtigt system og en meget dårlig teknologistak . Der er en simpel grund til det: de havde ikke brug for det, da de startede. Brug af mere tid på at designe dit system i stedet for kodning kan faktisk få dig til at mislykkes .

Denne artikel er trin for trin, hvordan man guider. Jeg vil vise dig, hvordan vi på Visage startede med det mindste system nogensinde og byggede et grundlæggende skalerbart distribueret system med høj tilgængelighed. Dette er en reel casestudie for at fjerne dine komplekser, hvis du aldrig har haft mulighed for at gøre det selv.

Da jeg først ankom til Visage som CTO, var jeg den eneste ingeniør. Jeg vidste intet om tech stack, men jeg sluttede mig, fordi jeg virkelig kunne lide tanken om at kunne rekruttere uden interne rekrutterere eller en HR-tjeneste. Dette var kerneidéen bag Visage: Crowdsourcing drevet af mange usynlige rekrutterere, der arbejder sammen om dine roller assisteret af kunstig intelligens, der ville kigge efter det mest passende talent for dig i løbet af få dage. Derefterdu interagerer direkte med dem, ingen mellemmand.

" Publikummet " i Crowdsourcing udløste øjeblikkeligt min tekniske hjerne: der kommer mange mennesker , der arbejder samtidigt og forventer god præstation fra hvor som helst i verden. Jeg kunne godt lide udfordringen.

Men systemmæssigt var tingene dårlige , virkelige dårlige . Dette er hvad jeg fandt, da jeg ankom:

  • En kompromitteret Wordpress-forekomst, der kører hundreder af forældede fejlbehæftede plugins, der kører i en VM på en delt server
  • Kompromitterede postkasser
  • Et lort af Google Docs og Spreadsheets.

Og dette er helt normalt. Igen var der ikke noget teknisk medlem på holdet, og jeg havde forventet noget som dette. Holdet havde stadig fokuseret på en forretningsmulighed og fik produktet til at virke som om det fungerede magisk, mens man gjorde alt manuelt! (Falske det, indtil du gør det). Og det var det, der virkelig var fantastisk.

Ingen overraskelse, at min første opgave var at genskabe VM, geninstallere en opdateret Wordpress-version, sørge for, at alle ændrer deres adgangskoder, etablerer en adgangskodepolitik og fjerner snesevis af malware på virksomhedens computere ... men lad os gå videre til systemovervejelser.

Fra Wordpress til en webapplikation

Dit første fokus, når du begynder at opbygge et produkt, skal være data . Data er det, der driver din virksomheds værdi . Det er det, du bruger hver dag til at træffe beslutninger, og hvad du viser dine investorer for at demonstrere fremskridt .

Du er nødt til at give mening om dine data, og det vil være et enormt spild af tid at genvinde dine data fra forskellige kilder med forskellige formater . Wordpress kan i mange tilfælde være et meget godt valg ved at spare en hel del ingeniørtid, men for deres behov måtte Visage-teamet installere smarte plugins, der ikke blev vedligeholdt længere. Som et resultat havde vi ingen kontrol over den genererede datamodel, og data, der ikke kunne passe modellen, blev spredt over snesevis af dokumenter og regneark.

Så medmindre der er et produkt derude, der allerede passer til 90% af dine behov, skal du overveje en ideel datamodel og designe og implementere et minimum levedygtigt produkt (MVP), der er i stand til at indeholde alle dine data.

Tænk derefter API . Din applikation skal have en API, det bliver kritisk, når du til sidst sælger den. Skal ikke straks op, men kod med tanke på skalerbarhed. Gør din API statsløs og så RESTful som du overhovedet kan, da alle forventer at være i stand til at forespørge om det ved hjælp af standard HTTP-metoder.

Vi valgte NodeJS i vores tilfælde, fordi det meste af vores kode bare ville behandle input og output. NodeJS blokeres ikke og leveres med et bibliotek, der er praktisk at designe API'er: ExpressJS .

Hvis du har brug for et kundeorienteret websted, har du flere muligheder. Først kan du oprette et lag på din applikationsserver, der genererer dine sider, eller du kan oprette et Javascript- program til en enkelt side , der betjenes af en statisk webhosting-server.

Hos Visage gik vi efter den anden mulighed og besluttede at oprette en applikation til brugere og en til administratorer. Dette var simpelthen fordi vi ville have meget større forventninger til brugerne end vi havde brug for hos administratorer og ønskede at holde begge kodebaser enkle (også af CORS- overvejelser senere). Sådan ser vores system ud:

Delegér følsom datalagring tidligt

Medmindre det er kritisk for din virksomhed, er der ingen god grund til at gemme følsomme personlige data i dine systemer. Sikkerhed er en kompleks sag, og hvis du ændrer din kode hver dag, indtil du finder dit produktmarked passende, vil den bryde. Antag, at alle, der ikke er bestemt, kan overtræde din ansøgning, hvis de virkelig vil.

Nøglen her er at ikke indeholde data, der ville være en hurtig gevinst for en hacker. Ingen berøver en bank, der ikke har penge . Hvis du designer et SaaS-produkt, har du sandsynligvis brug for godkendelse og online betaling. Der er mange tredjeparter, du kan integrere med, der vil håndtere det på en meget bedre måde, end du muligvis kunne.

Auth0 er for eksempel den mest kendte tredjepart, der håndterer godkendelse. Stripe er også en god mulighed for onlinebetalinger. De vil afsætte alle deres ressourcer og de bedste sikkerhedstekniske teams på planeten for at holde dine data sikre - ellers har de ikke en forretning.

Cloud-tjenester er dine bedste venner

Så på dette tidspunkt havde vi en måde at gemme alle vores data, godkendelse, online betaling og en webapp på, som klienter kunne bruge sammen med en API, som vi kunne sælge til partnere til forskellige brugssager. Vores brugerbase voksede, og det blev tydeligt, at de ønskede at kunne få adgang til appen når som helst. Så det var tid til at tænke over skalerbarhed og tilgængelighed .

Vi stole på en server, men den kunne kun håndtere så mange anmodninger, og skift af servere eller frigivelse af en ny version ville betyde, at applikationen blev fjernet under frigivelsen. Vores næste prioriteter var: belastningsbalancering , automatisk skalering , logning , replikering og automatiserede sikkerhedskopier . Selvfølgelig, hvis du er den eneste ingeniør i din virksomhed, ville det være fuldstændig galskab at prøve at tackle alle disse problemer alene.

Heldigvis lever vi i en tid, hvor kun en enkelt afrundet ingeniør nemt kan opbygge et sådant system om et par dage ved hjælp af Cloud-tjenester som Amazon Web Services , Google Cloud Services eller Azure . Vi besluttede at flytte vores systemer til AWS, fordi det på det tidspunkt var den mest komplette løsning, og vi havde 2 års gratis kreditter.

Dette er grunden til, at jeg for det meste vil tale om AWS-løsninger i dette indlæg, men der er tilsvarende tjenester på andre platforme. Dette er også den tid, vi valgte at starte vores moduler i Docker- containere af mange forskellige andre grunde, der ikke vil blive dækket af dette indlæg (du kan tjekke denne artikel for mere info: //medium.freecodecamp.org/amazon -fargate-farvel-infrastruktur-3b66c7e3e413).

Hvordan du beslutter dig for at køre dine applikationer, afhænger virkelig af din brugssag, som den fleksibilitet, du har brug for i forhold til den tid, du kan bruge på at administrere din infrastruktur.

Der er ikke noget godt eller dårligt svar.

Du kan vælge at containerize alle dine moduler og bruge en beholder management -system ligesom ECS / EKS i AWS eller Kubernetes motor i GCP. Hvis ikke, og du ikke selv vil beskæftige dig med ting som automatisk skalering og belastningsbalancering, kan du bruge Elastic Beanstalk eller App Engine.

Hvis du vil være fuld Serverless , kan du også kombinere brugen af ​​Lambda-funktioner og API Gateway. Vi besluttede at gå efter ECS. Vi implementerede 3 forekomster på tværs af 3 tilgængelighedszoner, en load-balancer , opsætning af automatisk skalering afhængigt af CPU-brug, integrerede alle vores containers logfiler med Cloudwatch og opsætningsdata for at se fejl , eksterne opkald og API-responstid .

Til vores database brugte vi MongoDB, fordi vores model passer godt til en NoSQL-database og for dens høje konsistens. Vi besluttede at udnytte MongoDB Atlas og implementerede 3 replikaer for at give mulighed for høj tilgængelighed. Blandt andre tjenester leverer Atlas automatisk skalering , automatiserede sikkerhedskopier og giver dig mulighed for at gå problemfrit tilbage i tid i tilfælde af katastrofe.

Vi besluttede også at være vært for alle vores statiske webfiler i S3 og brugte Cloudfront som et CDN, så vores JS-apps kan indlæses meget hurtigt overalt i verden og serveres så mange gange som ønsket. Cloudfare er også en god mulighed og tilbyder en DDOS-beskyttelse ud af kassen.

For enkelheds skyld besluttede vi at bruge rute 53 som vores DNS ved at bruge deres navneservere til alle vores domæner. Dette er en af ​​mine foretrukne tjenester på AWS. Det gør dit liv så meget lettere. Hver gang du vil tjene noget gennem et domænenavn, hvad enten det er en EC2- forekomst, en elastisk IP , en belastningsafbalancering , en Cloudfront- distribution eller noget rigtigt, privat eller offentligt, tager det dig minutter, fordi det er så godt integreret med alle andre tjenester.

Kombiner det med Certificate Manager, der giver dig mulighed for at få SSL-certifikater (jokertegn inkluderet) gratis på få minutter og distribuere dem på alle dine servere ved at markere et felt, og du har den hurtigste og mest pålidelige måde at aktivere HTTPS på alle dine moduler på. Farvel “Lad os kryptere” SSL-certifikater, som jeg var nødt til at forny og installere på mine servere hver tredje måned eller deromkring?

Beslut om en cachestrategi

Alle hader cacheadministration, caching kan ske i mange forskellige lag, og cache-relaterede problemer er svære at reproducere og et mareridt at fejle.

Desværre afhænger ydelsen af distribuerede systemer stærkt af en god cachestrategi . Der er mange gode artikler om gode cachingstrategier, så jeg vil ikke gå i detaljer. Bare vide, at hvis dine Statisk Web ressourcer er tunge, vil du sandsynligvis ønsker at drage fordel af din brugerens browser cache ved behændigt at bruge cache-control header.

Hvis din brugers modstående sider genereres på applikationsserverne igen og igen, skal du bruge en cacheproxy som blæksprutte . Men vigtigst af alt er der en stor chance for, at du kommer med de samme anmodninger til din database igen og igen. For at sænke din databasebelastning og spare dataoverførselstiden skal du bruge et cache-system til hukommelsesobjekt som memcached til objekter, der ofte bruges og sjældent opdateres .

Vi begyndte at overveje at bruge memcached, fordi vi ofte anmodede om de samme kandidatprofiler og jobtilbud igen og igen. Implementering af det på en hukommelsesoptimeret maskine øgede vores API- ydeevne med mere end 30%, når vi gennemsnitlige alle anmodningernes svartider på en dag. Memcached distribueres også, så det kan køre på forskellige servere, men fungerer stadig som om det bare er et stort hukommelsesrum til at gemme dine objekter.

Placering, placering, placering

Nu har vi et distribueret system, der ikke har et enkelt fejlpunkt (hvis du overvejer AWS ELB'er og et distribueret memcached) og kan automatisk skalere op og ned. Vi bruger også cache til at minimere netværksdataoverførsler. Ser godt ud. På det tidspunkt vil du sandsynligvis revidere dine tredjeparter for at se, om de vil absorbere belastningen så godt som dig.

Men stadig klagede nogle af vores brugere over, at appen var lidt langsommere for dem, især når de uploadede filer. Faktisk, selvom vores statiske webfiler blev cachelagret over hele verden (med tilladelse fra CDN), blev alle vores applikationsservere kun distribueret i det vestlige USA. Brugere fra Østasien oplevede meget mere ventetid, især for store dataoverførsler.

Løsningen var let: implementer nøjagtig den samme ECS-klynge på en ny region i Asien sammen med en ny belastningsafbalancering, og stole på Route 53 Geoproximity Routing for at dirigere brugere til den "nærmeste" load balancer. MongoDB Atlas giver dig også mulighed for at distribuere dine replikaer på tværs af regioner, så der ikke var behov for yderligere arbejde.

Konklusion

Mens det distribuerede system, du ser her, er blevet forenklet til dette indlæg, undersøgte vi de dele, du sandsynligvis vil se i mange moderne webapplikationer. Andre emner relateret til, men ikke dækket, er mikroservicearkitektur, filopbevaring og kryptering, databaseskæring, planlagte opgaver, asynkron parallel computing ... måske i det næste indlæg!

Mit hovedpunkt er: prøv ikke at opbygge det perfekte system, når du starter dit produkt. De fleste af dine designvalg styres af, hvad dit produkt gør, og hvem der bruger det. Du ved kun, at når du når produktmarkedets pasform og begynder at få et godt overblik over din brugerbase, og det kan tage måneder, år endda.

Fokuser på at finde ud af, hvad folk har brug for , og prøv at finde en løsning på deres problem, selvom det har mange manuelle trin . Tænk derefter på måder at automatisere , bruge din tid på at kode og ødelægge , og brug tredjeparter, hvor det giver mening.

Må ikke skaleres, men tænk altid, kod og planlæg for skalering. Byg dit system trin for trin , tag ikke fat i systemdesignproblemer baseret på funktioner, der endnu ikke er modne, og prøv endelig altid at finde den bedste afvejning mellem den tid, du bruger, og gevinsten i ydeevne, penge og sænket risiko.

Hvis du kunne lide denne artikel og fandt noget af det nyttigt, skal du trykke på den klappeknap og følge mig for flere artikler om arkitektur og udvikling! ?