Programmering

Serverløs computing med AWS Lambda, del 1

Serverløs computing kan være den hotteste ting inden for cloud computing i dag, men hvad er det nøjagtigt? Denne tutorial i to dele starter med en oversigt over serverløs computing - fra hvad det er, til hvorfor det betragtes som forstyrrende for traditionel cloud computing, og hvordan du kan bruge det til Java-baseret programmering.

Efter oversigten får du en praktisk introduktion til AWS Lambda, som af mange betragtes som den første Java-baserede løsning til serverløs computing i dag. I del 1 bruger du AWS Lambda til at opbygge, implementere og teste din første Lambda-funktion i Java. I del 2 integrerer du din Lambda-funktion med DynamoDB og bruger derefter AWS SDK til at påberåbe Lambda-funktioner i en Java-applikation.

Hvad er serverløs computing?

Sidste år talte jeg med en virksomhedspraktikant om forskellige arkitektoniske mønstre og nævnte serverløs arkitektur. Han bemærkede hurtigt, at alle applikationer kræver en server og ikke kan køre i luften. Praktikanten havde et punkt, selvom han manglede min. Serverløs computing er ikke en magisk platform til at køre applikationer.

Faktisk, serverløs computing betyder simpelthen, at du, udvikleren, ikke behøver det behandle serveren. En serverløs computerplatform som AWS Lambda giver dig mulighed for at opbygge din kode og implementere den uden nogensinde at skulle konfigurere eller administrere underliggende servere. Din implementeringsenhed er din kode; ikke containeren, der er vært for koden, eller den server, der kører koden, men simpelthen selve koden. Fra et produktivitetssynspunkt er der åbenlyse fordele ved at downloade detaljerne om, hvor koden er gemt, og hvordan eksekveringsmiljøet styres. Serverløs computing er også prissat baseret på metrics for eksekvering, så der er også en økonomisk fordel.

Hvad koster AWS Lambda?

På tidspunktet for denne skrivning er AWS Lambdas prisniveau baseret på antallet af henrettelser og udførelsens varighed:

  • Dine første millioner henrettelser om måneden er gratis, derefter betaler du 0,20 dollars pr. Million henrettelser derefter (0,0000,002 dollars per anmodning).
  • Varigheden beregnes fra det tidspunkt, hvor din kode begynder at køre, indtil den returnerer et resultat afrundet til de nærmeste 100 ms. Det opkrævede beløb er baseret på den mængde RAM, der er allokeret til funktionen, hvor omkostningerne er $ 0,00001667 for hvert GB-sekund.

Prisoplysninger og gratis niveautildelinger er lidt mere komplicerede end oversigten antyder. Besøg prisniveauet for at gå gennem et par prisfastsættelsesscenarier.

For at få en idé om, hvordan serverløs computing fungerer, lad os starte med den serverløse computing-eksekveringsmodel, som er illustreret i figur 1.

Steven Haines

Her er den serverløse udførelsesmodel i en nøddeskal:

  1. En klient fremsætter en anmodning til den serverløse computerplatform om at udføre en bestemt funktion.
  2. Den serverløse computerplatform kontrollerer først, om funktionen kører på nogen af ​​dens servere. Hvis funktionen ikke allerede kører, indlæser platformen funktionen fra et datalager.
  3. Platformen distribuerer derefter funktionen til en af ​​dens servere, som er forudkonfigureret med et eksekveringsmiljø, der kan køre funktionen.
  4. Den udfører funktionen og fanger resultatet.
  5. Det returnerer resultatet tilbage til klienten.

Undertiden kaldes serverløs computing Function as a Service (FaaS), fordi kornets granularitet er en fungere. Platformen udfører din funktion på sin egen server og orkestrerer processen mellem funktionsanmodninger og funktionsresponser.

Nanotjenester, skalerbarhed og pris

Tre ting betyder virkelig noget om serverløs computing: dens nanotjenestearkitektur; det faktum, at det praktisk talt er uendeligt skalerbart; og prisfastsættelsesmodellen forbundet med den næsten uendelige skalerbarhed. Vi vil grave i hver af disse faktorer.

Nanotjenester

Du har hørt om mikrotjenester, og du kender sandsynligvis til 12-faktor applikationer, men serverløse funktioner tager paradigmet for at nedbryde en komponent ned til dens bestanddele til et helt nyt niveau. Udtrykket "nanotjenester" er ikke et branchens anerkendt udtryk, men ideen er enkel: hver nanotjeneste skal implementere en enkelt handling eller et ansvar. For eksempel, hvis du ønskede at oprette en widget, ville oprettelsen være dens egen nanotjeneste; hvis du ønskede at hente en widget, ville hentning også være en nanotjeneste; og hvis du ville placere en ordre på en widget, ville denne ordre være endnu en nanotjeneste.

En nanotjenestearkitektur giver dig mulighed for at definere din applikation på et meget finkornet niveau. I lighed med testdrevet udvikling (som hjælper dig med at undgå uønskede bivirkninger ved at skrive din kode på niveau med individuelle tests) tilskynder en nanotjenestearkitektur til at definere din applikation med hensyn til meget finkornede og specifikke funktioner. Denne tilgang øger klarheden om, hvad du bygger, og reducerer uønskede bivirkninger fra ny kode.

Mikrotjenester vs nanotjenester

Microservices opfordrer os til at opdele en applikation i en samling af tjenester, der hver udfører en specifik opgave. Udfordringen er, at ingen virkelig har kvantificeret rækkevidde af en mikroservice. Som et resultat definerer vi mikrotjenester som en samling relaterede tjenester, der alle interagerer med den samme datamodel. Konceptuelt, hvis du har lavt niveau funktionalitet interagerer med en given datamodel, så skal funktionaliteten gå ind i en af ​​dens relaterede tjenester. Interaktioner på højt niveau skal foretage opkald til tjenesten i stedet for at spørge direkte til databasen.

Der er en løbende debat i serverløs computing om, hvorvidt der skal bygges Lambda-funktioner på niveau med mikrotjenester eller nanotjenester. Den gode nyhed er, at du ret nemt kan opbygge dine funktioner i begge granulariteter, men en mikroservicestrategi vil kræve lidt ekstra routinglogik i din anmodningshåndterer.

Fra et designperspektiv skal serverløse applikationer være meget veldefinerede og rene. Fra et implementeringsperspektiv skal du styre betydeligt flere implementeringer, men du vil også have mulighed for at implementere nye versioner af dine funktioner individuelt uden at påvirke andre funktioner. Serverløs computing er især velegnet til udvikling i store teams, hvor det kan hjælpe med at gøre udviklingsprocessen lettere og koden mindre fejlbehæftet.

Skalerbarhed

Ud over at introducere et nyt arkitektonisk paradigme, giver serverløse computerplatforme praktisk talt uendelig skalerbarhed. Jeg siger "praktisk talt", fordi der ikke er sådan noget som virkelig uendelig skalerbarhed. Til alle praktiske formål kan serverløse computerudbydere som Amazon dog håndtere mere belastning, end du muligvis kunne kaste på dem. Hvis du skulle styre opskalering af dine egne servere (eller skybaserede virtuelle maskiner) for at imødekomme øget efterspørgsel, skal du overvåge brugen, identificere hvornår du skal starte flere servere og tilføje flere servere til din klynge på det rigtige tidspunkt. Ligeledes, når efterspørgslen faldt, skal du manuelt nedskalere. Med serverløs computing fortæller du din serverløse computerplatform det maksimale antal samtidige funktionsanmodninger, du vil køre, og platformen skalerer for dig.

Priser

Endelig giver den serverfri beregningsprismodel dig mulighed for at skalere din skyregning baseret på brug. Når du har let brug, vil din regning være lav (eller ingen, hvis du forbliver i frit rækkevidde). Selvfølgelig stiger din regning med brugen, men forhåbentlig har du også nye indtægter til at understøtte din højere skyregning. Hvis du derimod skulle administrere dine egne servere, skulle du betale en basisomkostning for at køre det mindste antal krævede servere. Efterhånden som brugen steg, ville du opskalere i intervaller på hele servere snarere end trin på individuelle funktionsopkald. Den serverløse computermodel er direkte proportional med din brug.

AWS Lambda til serverløs computing

AWS Lambda er en serverløs computerplatform implementeret oven på Amazon Web Services-platforme som EC2 og S3. AWS Lambda krypterer og gemmer din kode i S3. Når en funktion bliver bedt om at køre, opretter den en "container" ved hjælp af dine runtime-specifikationer, distribuerer den til en af ​​EC2-forekomsterne i dens beregningsfarm og udfører denne funktion. Processen er vist i figur 2.

Steven Haines

Når du opretter en Lambda-funktion, konfigurerer du den i AWS Lambda og specificerer ting som runtime-miljøet (vi bruger Java 8 til denne artikel), hvor meget hukommelse der skal allokeres til det, identitets- og adgangsstyringsroller og metoden til udføre. AWS Lambda bruger din konfiguration til at konfigurere en container og distribuere containeren til en EC2-forekomst. Det udfører derefter den metode, du har angivet, i rækkefølgen af ​​pakke, klasse og metode.

På tidspunktet for denne skrivning kan du opbygge Lambda-funktioner i Node, Java, Python og senest C #. I forbindelse med denne artikel bruger vi Java.

Hvad er en Lambda-funktion?

Når du skriver kode designet til at køre i AWS Lambda, skriver du funktioner. Begrebet funktioner kommer fra funktionel programmering, der stammer fra lambda-calculus. Grundideen er at komponere en applikation som en samling funktioner, som er metoder, der accepterer argumenter, beregner et resultat og ikke har nogen uønskede bivirkninger. Funktionel programmering tager en matematisk tilgang til at skrive kode, der kan bevises at være korrekt. Selvom det er godt at huske funktionel programmering, når du skriver kode til AWS Lambda, er alt, hvad du virkelig har brug for at forstå, at funktionen er et indgangspunkt med en metode, der accepterer et inputobjekt og returnerer et outputobjekt.

Serverfri udførelsestilstande

Mens Lambda-funktioner kan køre synkront, som beskrevet ovenfor, kan de også køre asynkront og som reaktion på begivenheder. For eksempel kan du konfigurere en Lambda til at køre, hver gang en fil blev uploadet til en S3-spand. Denne konfiguration bruges undertiden til billed- eller videobehandling: når et nyt billede uploades til en S3-skovl, påkaldes en Lambda-funktion med en henvisning til billedet for at behandle det.

Jeg arbejdede med et meget stort firma, der udnyttede denne løsning til fotografer, der dækkede et maraton. Fotograferne var på kurset og tog fotografier. Når deres hukommelseskort var fyldt, indlæste de billederne på en bærbar computer og uploadede filerne til S3. Efterhånden som billeder blev uploadet, blev Lambda-funktioner udført for at ændre størrelse, vandmærke og tilføje en reference for hvert billede til dets løber i databasen.

Alt dette ville kræve meget arbejde at udføre manuelt, men i dette tilfælde blev arbejdet ikke kun behandlet hurtigere på grund af AWS Lambdas vandrette skalerbarhed, men også problemfrit skaleret op og ned igen og dermed optimeret virksomhedens skyregning.

Ud over at reagere på filer, der er uploadet til S3, kan lambdas udløses af andre kilder, såsom poster, der indsættes i en DynamoDB-database og analytisk informationsstreaming fra Amazon Kinesis. Vi ser på et eksempel med DynamoDB i del 2.

AWS Lambda fungerer i Java

Nu hvor du ved lidt om serverløs computing og AWS Lambda, vil jeg lede dig gennem opbygningen af ​​en AWS Lambda-funktion i Java.

download Hent koden Kildekode til applikationseksemplet til denne tutorial, "Serverløs computing med AWS Lambda." Oprettet af Steven Haines til JavaWorld.

Implementering af Lambda-funktioner

Du kan skrive en Lambda-funktion på en af ​​to måder:

  • Funktionen kan modtage en inputstrøm til klienten og skrive til en outputstrøm tilbage til klienten.
  • Funktionen kan bruge en foruddefineret grænseflade, i hvilket tilfælde AWS Lambda automatisk deserialiserer inputstrømmen til et objekt, overfører den til din funktion og serierer din funktions svar, inden den returneres til klienten.

Den nemmeste måde at implementere en AWS Lambda-funktion på er at bruge en foruddefineret grænseflade. For Java skal du først medtage følgende AWS Lambda-kernebibliotek i dit projekt (bemærk at dette eksempel bruger Maven):

 com.amazonaws aws-lambda-java-core 1.1.0 

Lad din klasse derefter implementere følgende grænseflade:

Notering 1. RequestHandler.java

 offentlig grænseflade RequestHandler {/ ** * Håndterer en Lambda-funktionsanmodning * @param-input Lambda-funktionens input * @param-kontekst Lambda-eksekveringsmiljøets kontekstobjekt. * @return Lambda-funktionens output * / public O handleRequest (I input, Context context); } 

Det RequestHandler interface definerer en enkelt metode: handleRequest (), der sendes et inputobjekt og en Sammenhæng objekt og returnerer et outputobjekt. For eksempel, hvis du skulle definere en Anmodning klasse og en Respons klasse, kan du implementere din lambda som følger:

 offentlig klasse MyHandler implementerer RequestHandler {public Response handleRequest (Request request, Context context) {...}} 

Alternativt, hvis du vil omgå den foruddefinerede grænseflade, kan du manuelt håndtere InputStream og OutputStream dig selv ved at implementere en metode med følgende signatur:

 public void handleRequest (InputStream inputStream, OutputStream outputStream, Context context) kaster IOException {...} 

Det Sammenhæng objekt giver information om din funktion og det miljø, den kører i, såsom funktionsnavnet, dens hukommelsesgrænse, dens logger og den resterende tid i millisekunder, som funktionen skal gennemføre, før AWS Lambda dræber den.