Implementazione di funzioni Serverless Node.js utilizzando Google Cloud
Pubblicato: 2022-03-11La creazione di software non si esaurisce con la scrittura di un buon codice. Viene completato quando il software viene distribuito ed è in grado di gestire le richieste correttamente e quando possiamo scalare senza ostacolare le prestazioni e il costo di esecuzione.
Probabilmente stai pensando a come hai il cloud computing per occuparti di tutte queste cose. "Allora, cos'è questa nuova cosa senza server , Vignes?"
L'elaborazione serverless è uno stile di architettura in cui il codice viene eseguito in una piattaforma cloud in cui non dobbiamo preoccuparci della configurazione hardware e software, della sicurezza, delle prestazioni e dei costi dei tempi di inattività della CPU. È un progresso del cloud computing che va oltre l'infrastruttura che astrae anche l'ambiente software. Significa che non è richiesta alcuna configurazione per eseguire il codice.
Con serverless, il seguente sarà il tuo stile di lavoro:
Sviluppa il codice.
Carica il codice sul fornitore di servizi.
Configura il trigger (una richiesta HTTP, nel nostro caso).
Il nostro lavoro è finito! Ora il provider della piattaforma si occuperà delle richieste in arrivo e del ridimensionamento.
Introduzione ai microservizi serverless
L'architettura serverless è spesso abbinata a un design in stile microservizi. Un microservizio è una parte autonoma di un grande software che gestisce le richieste per un modulo specifico. Creando microservizi che possono essere eseguiti in un ambiente serverless, diventa facile mantenere il codice e velocizzare le distribuzioni.
Introduzione ad AWS Lambda e GCF, un confronto
Una funzionalità serverless è spesso chiamata "back-end come servizio" o "funzione come servizio". Il numero di fornitori di computer serverless sta iniziando ad aumentare. Tuttavia, alcuni dei grandi player tradizionali forniscono anche opzioni serverless, come AWS Lambda Functions di Amazon Web Services e Google Cloud Functions (GCF) di Google Cloud, l'ultima delle quali, mentre attualmente in versione beta, è quella che sto usando. Sebbene funzionino in modo simile, ci sono alcune differenze importanti tra di loro.
| AWS Lambda | Funzioni Google Cloud | |
|---|---|---|
| Supporto linguistico | Node.js, Python, C#, Java | Node.js |
| Trigger | DynamoDB, Kinesis, S3, SNS, gateway API (HTTP), CloudFront e altro | HTTP, Cloud PubSub, Secchio di archiviazione cloud |
| Tempo massimo di esecuzione | 300 secondi | 540 secondi |
In questo articolo, analizzeremo il processo di implementazione della distribuzione del codice serverless utilizzando GCF. Google Cloud Functions è una soluzione di calcolo asincrona leggera, basata su eventi che consente di creare piccole funzioni monouso che rispondono agli eventi cloud senza la necessità di gestire un server o un ambiente di runtime.
GCF ha tre possibili implementazioni separate in base ai trigger.
Trigger HTTP Instrada le richieste HTTP alle funzioni cloud
Trigger interno di Google pub/sub Indirizza le richieste di pubblicazione e abbonamento alle funzioni cloud
Attivazione del bucket di archiviazione cloud Indirizza tutte le modifiche apportate al bucket di archiviazione alla funzione cloud
Creiamo una configurazione basata su trigger HTTP utilizzando Google Cloud Functions
Google Cloud Functions non richiede alcuna configurazione o installazione speciale aggiuntiva. GCF garantisce che l'ambiente del nodo predefinito sia configurato e pronto per l'esecuzione. Quando una funzione cloud viene creata con HTTP come trigger, fornisce un URL per attivare la funzione. Confrontando con AWS Lambda, che utilizza un gateway API come mezzo per comunicare con esso, Google Cloud Functions fornisce l'URL immediatamente in base projectID e alla regione.
Creazione di un'applicazione Serverless Node.js
Per rendere il nostro codice eseguibile in GCF, dovremmo racchiudere il codice all'interno di una singola funzione. GCF chiamerà quella particolare funzione ogni volta che si verifica il trigger. I possibili modi per farlo sono il caricamento,
File singolo: esporta una funzione predefinita che chiamerà altre funzioni in base alla richiesta.
Più file: avere un file
index.jsche richiede tutti gli altri file ed esporta la funzione predefinita come punto di partenza.Più file: avere un file principale configurato in
package.jsonusando"main": "main.js"come punto di partenza.
Uno qualsiasi dei metodi di cui sopra funzionerà.
GCF ha una particolare versione di runtime di Node supportata. Assicurati che il codice sia scritto per supportare quella particolare versione. Al momento della creazione di questo post, GCF supporta la versione Node v6.11.1.
Per creare una funzione, ci sono alcune opzioni da considerare.
Memoria Indica quanta memoria è necessaria per elaborare la richiesta per un runtime. Definito in MB. Per una piccola applicazione, 128 MB dovrebbero essere sufficienti, ma possono essere aumentati fino a 2 GB.
Timeout Timeout, come suggerisce il nome, definisce il timeout di esecuzione del codice previsto. Successivamente, il codice verrà ucciso e interrotto. Qualsiasi esecuzione dopo questo punto si interromperà bruscamente. Il timeout massimo è di 540 secondi.
Funzione da eseguire Sebbene sia possibile esportare più di una funzione dal file del gestore principale, è necessario configurare una funzione che dovrebbe essere attivata per l'elaborazione della richiesta. Ciò consente allo sviluppatore di avere più punti di ingresso in base al metodo/URL HTTP.

Per caricare il codice, fai semplicemente un copia incolla del codice per creare un portale di funzioni. Per più di un file, comprimi il contenuto e carica il file. Assicurati che, nel caso di un file ZIP, ci dovrebbe essere un file index.js o un file package.json con il file principale menzionato.
Qualsiasi dipendenza del modulo NPM deve essere menzionata in package.json . GCF tenta di installare i moduli menzionati nel file package.json durante la prima installazione.
Creiamo un semplice gestore per restituire uno stato 200 e alcuni messaggi. Crea una funzione e aggiungi il codice seguente all'origine.
exports.httpServer = function httpServer(req, res) { console.log(req); res.status(200).send('Server is working'); } Una volta creata la funzione, aprire l'URL fornito per attivare la funzione. Dovrebbe rispondere come il seguente.
Ora esaminiamo l'oggetto req nei log. Per visualizzare i log, GCF fornisce opzioni direttamente dalla console. Fare clic sui punti verticali e aprire l'opzione dei registri.
Ora aggiorniamo il codice per gestire percorsi semplici per /users .
Il codice seguente viene utilizzato per gestire una semplice richiesta GET & POST per il percorso /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); } } Dopo l'aggiornamento, testiamolo ora nel browser, ma questa volta con /users alla fine.
Questo è figo. Abbiamo creato un server HTTP di base con routing.
Operazioni e debug
Se il codice fosse dove la storia finiva, non cercheresti opzioni di infrastruttura come le applicazioni serverless Node.js. Ecco un breve riepilogo di come occuparsi di attività comuni come la distribuzione e il debug. Cose che gli sviluppatori Node.js fanno già per altre applicazioni.
Distribuzione:
Il codice per le funzioni può essere distribuito in quattro modi.
Copia incollando il codice nella console
Caricamento di un file ZIP
Distribuzione dal bucket di archiviazione cloud come file ZIP
Distribuzione dal repository di origine cloud
L'opzione più conveniente è, ovviamente, la distribuzione da un repository di origine.
Invocazione:
Durante la creazione della funzione, Console fornisce l'URL HTTP per attivare la funzione che è nel formato: https://<region>-<project-id>.cloudfunctions.net/<function-name>
La funzione di AWS Lambda presenta problemi di avvio a freddo che fanno sì che l'esecuzione della funzione richieda più tempo per l'avvio. Una volta avviate, le seguenti esecuzioni risponderanno normalmente. Questo tempo di avviamento aggiuntivo iniziale è indicato come avviamento a freddo. Sebbene non disponiamo della documentazione ufficiale per GCF relativa a questo argomento, i problemi di avvio a freddo non si sono manifestati durante i nostri test.
Debug:
GCF si integra con il servizio Stackdriver Logging in Google Cloud. Tutti i registri e gli errori della console verranno registrati qui e ciò aiuta a eseguire il debug del codice già distribuito.
Test:
La console fornisce opzioni per testare la funzione passando un JSON come input. La funzione verrà chiamata con JSON come input e l'output verrà visualizzato nella console. La richiesta (input) e la risposta sono simili al framework Express.js e possono essere testate durante il processo di sviluppo stesso. Se hai bisogno di un aggiornamento sui test di Node.js, consulta A Node.js Guide per eseguire effettivamente i test di integrazione
Limitazioni e passaggi successivi
L'uso delle funzioni serverless ha i suoi vantaggi, ma ha anche delle limitazioni
Blocco del fornitore: limita il codice che scriviamo a un particolare fornitore di servizi. Lo spostamento del codice su un altro provider richiede la riscrittura del codice con sforzi significativi per la migrazione. Poiché questo può essere un grosso problema, dovremmo prestare molta attenzione quando scegliamo un fornitore di servizi.
Limitazioni nel numero di richieste e risorse hardware: i provider spesso limitano il numero di richieste parallele che una funzione gestirà alla volta. Ci sono anche limitazioni di memoria. Questi tipi di restrizioni possono essere aumentati parlando con il provider, ma esisteranno comunque.
Google Cloud Functions sta maturando e migliorando molto. Viene ancora migliorato e aggiornato frequentemente, specialmente nelle lingue che può supportare. Se hai intenzione di utilizzare le funzioni di Google Cloud, tieni d'occhio i log delle modifiche per evitare modifiche di interruzione nell'implementazione.
Ulteriori letture sul blog di Toptal Engineering:
- Lavorare con TypeScript e Jest Support: un tutorial AWS SAM
