Serverløs beste praksis

I samfunnet har vi diskutert beste praksis i mange år, men det er noen få som har vært relativt akseptert i det meste av den tiden.

De fleste serverløse utøvere som abonnerer på disse praksisene fungerer i stor skala. Løftet om serverløs spiller for det meste både i stor skala og bursty arbeidsmengde fremfor på et relativt lavt nivå, så mange av disse beste praksisene kommer fra skalavinkelen, f.eks. Nordstrøm i detaljhandel og iRobot i IoT. Hvis du ikke har som mål å skalere så langt, kan du sannsynligvis komme deg unna uten å følge disse beste praksisene uansett.

Og husk at beste praksis ikke er “den eneste praksis”. Beste praksis er avhengig av et sett av underliggende forutsetninger. Hvis disse antagelsene ikke passer til din brukssak, kan det hende at de beste fremgangsmåtene ikke passer.

Min viktigste antagelse er at alle bygger sin applikasjon for å kunne kjøre i skala (selv om det aldri ender med å bli kjørt i skala).

Så dette er min beste praksis slik jeg ser dem.

Hver funksjon skal bare gjøre en ting

Det handler om funksjonsfeil og skaleringsisolering.

Hvis du bruker en brytererklæring i funksjonen din, gjør du det sannsynligvis galt.

Mange opplæringsprogrammer og rammer fungerer på grunnlag av en stor monolitisk funksjon bak en enkelt proxy-rute og bruker bryter-uttalelser. Jeg misliker dette mønsteret. Det skalerer ikke godt, og har en tendens til å lage store og komplekse funksjoner.

Problemet med en / noen få funksjoner som kjører hele appen din, er at når du skalerer skal du ende opp med å skalere hele applikasjonen, i stedet for å skalere det spesifikke elementet.

Hvis du har en del av webapplikasjonen din som får 1 million samtaler, og en annen som får 1000 samtaler, må du optimalisere funksjonen din for millionen, mens du inkluderer all koden for tusen. Det er bortkastet, og du kan ikke enkelt optimalisere for tusen. Skill dem ut. Det er så mye verdi i det.

Funksjoner kaller ikke andre funksjoner

Funksjoner som kaller andre funksjoner er et antimønster.

Det er veldig få kantsaker der dette er et gyldig mønster, men de blir ikke lett brutt ned.

I utgangspunktet ikke gjør det. Du dobler ganske enkelt kostnadene dine, og gjør feilsøking mer kompleks og fjerner verdien av isolasjonen av funksjonene dine.

Funksjoner skal skyve data til et datalager eller en kø, noe som skal utløse en annen funksjon hvis mer arbeid er nødvendig.

Bruk så få biblioteker i funksjonene dine som mulig (helst null)

Denne virker åpenbar for meg.

Funksjonene har kaldstarter (når en funksjon startes for første gang) og varmstarter (den er startet, og er klar til å bli utført fra det varme bassenget). Kaldestart påvirkes av en rekke ting, men størrelsen på zip-filen (eller koden lastes opp imidlertid) er en del av den. Antall biblioteker som må øyeblikkelig.

Jo mer kode du har, jo saktere er det å starte kald.

Jo flere biblioteker som trenger tilrettelegging, jo saktere er det å starte kaldt.

Som et eksempel er Java et glimrende utøvende språk på en varm start på noen plattformer. Men hvis du bruker mange biblioteker, kan du finne at det tar mange mange sekunder å starte kaldt. Du trenger nesten ikke trenger dem, og ytelsen på kaldstart hindrer ikke bare ved oppstart, men også på skalering.

Som et annet poeng er jeg en stor tro på at utviklere bare bruker biblioteker når det er nødvendig, og det betyr å starte med ingen, og slutte med ingen med mindre jeg ikke kan bygge det som trengs uten det.

Ting som express er bygget for servere, og serverløse applikasjoner trenger ikke alle elementene der inne. Så hvorfor introdusere alle koder og avhengigheter? Hvorfor ta med overflødig kode? Det er ikke bare noe som aldri vil bli kjørt, men det kan innføre en sikkerhetsrisiko.

Det er så mange grunner til at dette er en god praksis. Selvfølgelig, hvis det er et bibliotek som du har testet, kjenner og stoler på, så absolutt ta det inn, men nøkkelelementet der er å teste, kjenne og stole på koden. Etter en tutorial er ikke det samme.

Unngå å bruke tilkoblingsbaserte tjenester, f.eks. RDBMS

Bare ikke med det.

Denne vil få meg i mest trøbbel. Mange nettapplikasjoner vil hoppe på “men RDBMS er det vi vet” båndtvungen.

Det handler ikke om RDBMS. Det handler om tilkoblingene.

Serverløs fungerer best med tjenester i stedet for tilkoblinger.

Tjenestene er ment å returnere svar på forespørsler virkelig raskt og for å håndtere kompleksiteten i datasjiktet bak tjenesten. Dette er av stor verdi på det serverløse rommet, og hvorfor noe som DynamoDB passer så godt innenfor det serverløse paradigmet.

For å være ærlige, serverløse mennesker er ikke mot RDBMS, de er mot tilkoblinger. Tilkoblinger tar tid, og hvis du ser for deg at en funksjon skaleres opp, trenger hvert funksjonsmiljø en tilkobling, og du introduserer både en flaskehals og en I / O-vente i den kalde starten av funksjonen. Det er unødvendig.

Så hvis du må bruke en RDBMS, men legger en tjeneste som håndterer tilkoblingssammenslåing i midten, kan det hende at en automatisk skaleringsbeholder med noen beskrivelse bare er å håndtere det.

Det største poenget å gjøre her er at serverløs arkitektur kan hende at du trenger å revurdere datalaget ditt. Det er ikke feilen med serveren. Hvis du prøver å bruke den nåværende datalagstenkningen din og den ikke fungerer, er det sannsynligvis en mangel på forståelse av serverløse arkitekturer.

Én funksjon per rute (hvis du bruker HTTP)

Unngå å bruke enkeltfunksjons proxy der det er mulig. Det skalerer ikke godt og hjelper ikke å isolere problemer. Det er tilfeller hvor du kan unngå dette, f.eks. der funksjonaliteten til en serie ruter er bundet strengt til et enkelt bord og det er veldig mye koblet fra resten av applikasjonen, men det er en viktig sak i de fleste applikasjoner jeg har jobbet i.

Dette tilfører kompleksitet når det gjelder styring, men det hjelper virkelig når det gjelder isolering av feil og problemer når applikasjonen skaleres. Begynn som du mener å fortsette.

Men da brukte du et slags konfigurasjonsadministrasjonsverktøy uansett for å kjøre alt, ikke sant? Og du har allerede brukt CI- og CD-verktøy av noe slag, ikke sant? Du må fremdeles DevOps med serverløs.

Lær å bruke meldinger og køer (async FTW)

Serverløse applikasjoner har en tendens til å fungere best når applikasjonen er asynkron. Dette er ikke rett frem for webapplikasjoner der tendensen er å gjøre svar på forespørsler og mye spørring.

Når du går tilbake til funksjonene som ikke kaller andre funksjoner, er det viktig å påpeke at det er slik du kjeder sammen. En kø fungerer som en effektbryter i kjedingsscenariet, slik at hvis en funksjon svikter, kan du enkelt tømme ned en kø som har blitt sikkerhetskopiert på grunn av en feil, eller skyve meldinger som ikke klarer å være dødbokskø.

I utgangspunktet, lær hvordan distribuerte systemer fungerer.

Med klientapplikasjoner med en serverløs back-end, er den beste tilnærmingen å se på CQRS. Å skille poenget med å hente inn data fra punktet for å legge inn data er nøkkelen til denne typen mønstre.

Dataflyter, ikke datasjøer

I et serverløst system flyter dataene dine gjennom systemet ditt. Det kan havne i en datasjø, men sannsynligheten er at mens den er i det serverløse systemet ditt, er det i en slags flyt. Så behandle alle data som om de er i bevegelse, ikke i ro på noe tidspunkt.

Det er ikke alltid mulig, men prøv å unngå spørring fra en datasjø i et serverløst miljø.

Serverløs krever at du vurderer datalaget ditt betydelig. Dette er den største guttene med nye mennesker som kommer til serverløse som har en tendens til å strekke seg etter RDBMS og falle flat, ikke bare fordi skaleringen fanger dem ut, men deres datastrukturer blir for stive for raskt.

Du vil oppdage at strømningene dine vil endres etter hvert som applikasjonen din endres og skalaen endrer alt. Hvis alt du trenger å gjøre er å omdirigere en flyt, er det enkelt. Det er langt vanskeligere å demme en innsjø.

Jeg vet at dette punktet er litt mer "der ute" enn andre, men det er ikke en rett frem.

Bare å kode for skala er en feil, du må vurdere hvordan det skalerer

Det er veldig enkelt å lage din første serverløse applikasjon, og se den skalere. Hvis du ikke forstår hva du har gjort selv, kan du lett falle i den fellen du kan med hver annen autoskalering.

Hvis du ikke vurderer søknaden din og hvordan den skaleres, konfigurerer du deg for problemer. Hvis du gjør noe med en langsom kald start (mange biblioteker og bruker en RDBMS for eksempel) og deretter får en pigg i bruk, kan du ende opp med å øke samtidig funksjonalitet for funksjonen din, og deretter maksimere forbindelsene dine, og bremse applikasjonen ned.

Så ikke slipp en applikasjon inn, og tenk deg at den vil fungere den samme under belastning. Å forstå applikasjonen din under belastning er fremdeles en del av jobben.

Konklusjon

Det er mange flere ting jeg kunne ha lagt inn her, og dette er min mening om de tingene jeg må forklare folk når jeg snakker med dem.

Jeg har ikke nevnt ting som hvordan du planlegger søknaden din, eller hvordan du vurderer å koste ut en applikasjon eller noe sånt da det er litt utenfor omfanget.

Ser frem til å høre andre menneskers tanker. Ganske sikker på at jeg kommer til å få en flom av folk som forteller meg at jeg tar feil om RDBMS. Som med containere, hater jeg ikke RDBMS, men liker å bruke de riktige verktøyene for de riktige jobbene. Kjenn verktøyene dine!