Implementarea funcțiilor Serverless Node.js folosind Google Cloud

Publicat: 2022-03-11

Crearea de software nu se termină cu scrierea unui cod bun. Acesta este finalizat atunci când software-ul este implementat și capabil să gestioneze cererile în mod corespunzător și când putem scala fără a împiedica performanța și costul rulării acestuia.

Probabil că vă gândiți la modul în care aveți cloud computing pentru a vă ocupa de toate aceste lucruri. — Deci, ce este acest nou lucru fără server , Vignes?

Funcții Node.js fără server folosind Google Cloud

Calculul fără server este un stil de arhitectură în care codul este executat într-o platformă cloud în care nu trebuie să ne facem griji pentru configurarea hardware și software, securitate, performanță și costurile de inactivitate a procesorului. Este un progres al cloud computing-ului care depășește infrastructura care face abstractie și de mediul software. Înseamnă că nu este necesară nicio configurație pentru a rula codul.

Cu serverless, următorul va fi stilul tău de lucru:

  1. Dezvoltați codul.

  2. Încărcați codul la furnizorul de servicii.

  3. Configurați declanșatorul (o solicitare HTTP, în cazul nostru).

Munca noastră este gata! Acum furnizorul platformei se va ocupa de cererile primite și de scalare.

Introducere în microservicii fără server

Arhitectura fără server este adesea cuplată cu un design în stil microservicii. Un microserviciu este o parte de sine stătătoare a unui software mare care gestionează solicitările pentru un anumit modul. Prin crearea de microservicii care pot rula într-un mediu fără server, devine ușor să mențineți codul și să accelerați implementările.

Introducere în AWS Lambda și GCF, o comparație

O caracteristică fără server este adesea numită „back-end ca serviciu” sau „funcționare ca serviciu”. Numărul furnizorilor de calculatoare fără server începe să crească. Cu toate acestea, unii dintre marii jucători tradiționali oferă, de asemenea, opțiuni fără server, cum ar fi AWS Lambda Functions de la Amazon Web Services și Google Cloud Functions (GCF), cea din urmă dintre acestea, deși sunt în prezent beta, este ceea ce folosesc. Deși funcționează în mod similar, există câteva diferențe importante între ele.

AWS Lambda Funcții Google Cloud
Suport lingvistic Node.js, Python, C#, Java Node.js
Declanșatoare DynamoDB, Kinesis, S3, SNS, gateway API (HTTP), CloudFront și altele HTTP, Cloud PubSub, compartiment de stocare în cloud
Timp maxim de executie 300 de secunde 540 de secunde

În acest articol, vom trece prin procesul de implementare a implementării codului fără server folosind GCF. Google Cloud Functions este o soluție de calcul asincronă ușoară, bazată pe evenimente, care vă permite să creați funcții mici, cu un singur scop, care răspund la evenimentele din cloud fără a fi nevoie să gestionați un server sau un mediu de rulare.

GCF are trei implementări posibile separate pe baza declanșatorilor.

  1. Declanșatorul HTTP Direcționează cererile HTTP către funcțiile cloud

  2. Declanșator intern Google pub/sub Rute de publicare și solicitări de abonare la funcțiile cloud

  3. Declanșatorul compartimentului de stocare în cloud Direcționează orice modificări aduse compartimentului de stocare către funcția cloud

Să creăm o configurare bazată pe declanșare HTTP utilizând funcțiile Google Cloud

Google Cloud Functions nu necesită nicio configurare sau instalare specială suplimentară. GCF asigură că mediul de nod implicit este configurat și gata de execuție. Când o funcție cloud este creată cu HTTP ca declanșator, aceasta oferă o adresă URL pentru declanșarea funcției. În comparație cu AWS Lambda, care folosește un gateway API ca mediu pentru a comunica cu acesta, Google Cloud Functions furnizează imediat adresa URL pe baza projectID -ului proiectului și a regiunii.

Diagrama Google Cloud Platform - Cloud Functions și AWS Lambda

Crearea unei aplicații Serverless Node.js

Pentru a face codul nostru executabil în GCF, ar trebui să încapsulăm codul într-o singură funcție. GCF va apela acea funcție specială ori de câte ori apare declanșarea. Modalitățile posibile de a face acest lucru sunt încărcarea,

  1. Fișier unic: Exportați o funcție implicită care va apela alte funcții pe baza solicitării.

  2. Fișiere multiple: aveți un fișier index.js care necesită toate celelalte fișiere și exportă funcția implicită ca punct de plecare.

  3. Mai multe fișiere: aveți un fișier principal configurat în package.json folosind "main": "main.js" ca punct de plecare.

Oricare dintre metodele de mai sus va funcționa.

GCF are o anumită versiune de rulare Node acceptată. Asigurați-vă că codul este scris pentru a accepta versiunea respectivă. La momentul creării acestei postări, GCF acceptă versiunea Node v6.11.1.

Pentru a crea o funcție, există câteva opțiuni de luat în considerare.

  1. Memorie Aceasta indică câtă memorie este necesară pentru a procesa cererea pentru un timp de rulare. Definit în MB. Pentru o aplicație mică, 128MB ar trebui să fie suficient, dar poate crește până la 2GB.

  2. Timeout Timeout, după cum sugerează și numele, definește timpul de expirare așteptat pentru executarea codului. După aceasta, codul va fi ucis și oprit. Orice execuție după acest punct se va opri brusc. Timeout maxim este de 540 de secunde.

  3. Funcție de executat Deși mai multe funcții pot fi exportate din fișierul de gestionare principal, trebuie să configuram o funcție care ar trebui să fie declanșată pentru procesarea cererii. Acest lucru permite dezvoltatorului să aibă mai multe puncte de intrare bazate pe metoda HTTP/URL.

Pentru a încărca codul, pur și simplu faceți o copie-lipire a codului pentru a crea un portal de funcții. Pentru mai mult de un fișier, arhivați conținutul și încărcați fișierul. Asigurați-vă că, în cazul unui fișier ZIP, ar trebui să existe fie un fișier index.js , fie un fișier package.json cu fișierul principal menționat.

Orice dependență de modul NPM ar trebui menționată în package.json . GCF încearcă să instaleze modulele menționate în fișierul package.json în timpul instalării pentru prima dată.

Să creăm un handler simplu pentru a returna o stare 200 și un mesaj. Creați o funcție și adăugați următorul cod la sursă.

 exports.httpServer = function httpServer(req, res) { console.log(req); res.status(200).send('Server is working'); } 

Captură de ecran a funcției care se creează

Odată ce funcția este creată, deschideți adresa URL furnizată pentru a declanșa funcția. Ar trebui să răspundă după cum urmează.

Captură de ecran a ieșirii browserului „Serverul funcționează”

Acum, să examinăm obiectul req din jurnale. Pentru a vizualiza jurnalele, GCF oferă opțiuni chiar din consolă. Faceți clic pe punctele verticale și deschideți opțiunea jurnalele.

Captură de ecran cu deschiderea opțiunii de jurnal

Acum, să actualizăm codul pentru a gestiona rute simple pentru /users .

Următorul cod este utilizat pentru a gestiona o solicitare simplă GET & POST pentru ruta /users :

 exports.httpServer = function httpServer(req, res) { const path = req.path; switch(path) { case '/users': handleUsers(req, res); break; default: res.status(200).send('Server is working'); } }; const handleUsers = (req, res) => { if (req.method === 'GET') { res.status(200).send('Listing users...'); } else if (req.method === 'POST') { res.status(201).send('Creating User...') } else { res.status(404); } }

După actualizare, să-l testăm acum în browser, dar de data aceasta cu /users la sfârșit.

Captură de ecran a ieșirii browserului „Listing users...”

Asta e tare. Am creat un server HTTP de bază cu rutare.

Operațiuni și depanare

Dacă codul ar fi locul unde s-a încheiat povestea, nu ați căuta opțiuni de infrastructură, cum ar fi aplicațiile Node.js fără server. Iată un scurt rezumat despre cum să vă ocupați de sarcini obișnuite, cum ar fi implementarea și depanarea. Lucruri pe care dezvoltatorii Node.js le fac deja pentru alte aplicații.

Implementare:

Codul pentru funcții poate fi implementat în patru moduri.

  • Copiați, inserați codul în consolă

  • Încărcarea unui fișier ZIP

  • Implementarea din compartimentul de stocare în cloud ca fișier ZIP

  • Implementarea din depozitul sursă cloud

Cea mai convenabilă opțiune este, evident, implementarea dintr-un depozit sursă.

Invocare:

În timpul creării funcției, Consola furnizează adresa URL HTTP pentru a declanșa funcția, care este în formatul: https://<region>-<project-id>.cloudfunctions.net/<function-name>

Funcția AWS Lambda are probleme de pornire la rece, ceea ce face ca execuția funcției să dureze mai mult pentru pornire. Odată pornit, următoarele execuții vor răspunde normal. Acest timp suplimentar inițial de pornire se numește pornire la rece. Deși nu avem documentația oficială pentru GCF legată de acest subiect, problemele de pornire la rece nu au apărut în timpul testării noastre.

Depanare:

GCF se integrează cu serviciul Stackdriver Logging din Google Cloud. Toate jurnalele și erorile din consolă vor fi înregistrate aici și ajută la depanarea codului care este deja implementat.

Testare:

Consola oferă opțiuni pentru a testa funcția prin trecerea unui JSON ca intrare. Funcția va fi apelată cu JSON ca intrare și ieșirea va fi afișată în consolă. Cererea (intrarea) și răspunsul sunt similare cu cadrul Express.js și pot fi testate unitar în timpul procesului de dezvoltare în sine. Dacă aveți nevoie de o reîmprospătare a testării Node.js, consultați Ghidul Node.js pentru a face efectiv teste de integrare

Limitări și pași următori

Utilizarea funcțiilor fără server are propriile sale avantaje, vine și cu limitări

  • Blocarea furnizorului: limitează codul pe care îl scriem unui anumit furnizor de servicii. Mutarea codului la alt furnizor necesită rescrierea codului cu eforturi semnificative către migrare. Deoarece aceasta poate fi o problemă mare, ar trebui să fim foarte atenți atunci când alegem un furnizor de servicii.

  • Limitări în numărul de solicitări și resurse hardware: Furnizorii limitează adesea numărul de solicitări paralele pe care o funcție le va gestiona la un moment dat. Există și restricții de memorie. Aceste tipuri de restricții pot fi crescute mai mult vorbind cu furnizorul, dar vor exista în continuare.

Google Cloud Functions se maturizează și se îmbunătățește foarte mult. Este încă îmbunătățit și actualizat frecvent, în special în limbile pe care le poate suporta. Dacă intenționați să utilizați funcțiile Google Cloud, fiți cu ochii pe jurnalele de modificări pentru a evita orice modificări nerespective în implementare.


Citiți suplimentare pe blogul Toptal Engineering:

  • Lucrul cu TypeScript și suport Jest: un tutorial AWS SAM