Quotidianamente ci troviamo ad affrontare la progettazione di soluzioni innovative la cui mission principale è quella di coinvolgere utenti sia interni che esterni all’azienda.
Per riuscire a raggiungere questo obiettivo è fondamentale riuscire a realizzare soluzioni utili nel contesto in cui sono inserite ma soprattutto fare in modo che siano disponibili in ogni momento in cui l’utente lo richiede.

Qualche mese fa ci siamo trovati a dover ragionare sullo sviluppo di una soluzione che fosse in grado di raggiungere un target di 2 milioni di utenti e che quindi offrisse scalabilità. Non riuscivamo a prevedere il carico di accesso degli utenti al sistema ma volevamo garantire affidabilità nell’erogazione del servizio senza dover prevedere un monitoraggio attivo e costante per la sua corretta esecuzione.
Quando i progetti hanno come obiettivo questi numeri, le incognite successive allo sviluppo quali: attività di manutenzione, concorrenza di accesso ai dati, consistenza dei dati ed attacchi informatici, sono sempre dietro l’angolo.
Per questo motivo durante la fase di progettazione abbiamo deciso di realizzare, a supporto del progetto, un’architettura Serverless interamente basata su tecnologia AWS.

L’obiettivo di questo articolo è di condividere con voi gli strumenti utilizzati ed i vantaggi raggiunti in questi mesi di live del progetto.

Per architettura Serverless si intende un’architettura dove gli sviluppatori possono concentrarsi esclusivamente sullo sviluppo del codice (Leggi qui l’intervista a Danilo Poccia AWS Technical Evangelist), senza doversi preoccupare della gestione di flotte di server per l’esecuzione e demandando al provider di servizi Cloud, in questo caso Amazon Web Services, le attività di amministrazione delle risorse garantendo così di raggiungere più facilmente un livello adeguato di sicurezza e affidabilità.

L’infrastruttura serverless che abbiamo realizzato utilizza le seguenti componenti:

  • API Gateway: servizio per creare ed esporre API
  • Lambda: esecuzione di codice
  • DynamoDB: database NoSQL

API Gateway

API Gateway è un servizio full managed per la creazione di servizi Restful JSON (e non solo).

Le caratteristiche principali sono:

  • possibilità di creare più API per account;
  • possibilità di creare, per ogni API, delle risorse sotto forma di chiamate REST, e per ognuna di queste creare dei metodi (GET, POST, ecc)
  • possibilità di gestire più stage in cui effettuare il deploy dell’API (ad es: test e produzione)
  • gestione dei mapping dei dati inviati nella chiamata REST verso la funzione lambda, oltre che il mapping di diverse variabili tra cui:
    • stage
    • parametri in query e path
    • header

Il vantaggio più rilevante derivante dall’uso di API Gateway è proprio quello di non doversi occupare di gestire in maniera diretta scalabilità e performance, essendo il tutto completamente gestito da AWS in base al numero di richieste alle API.

Se si decide di utilizzare API Gateway va tenuto presente che il timeout massimo per ogni singola chiamata è di 10 secondi. Di conseguenza il codice che viene eseguito in risposta alla chiamata deve essere in grado di fornire un risultato in tempi molto brevi.

Lambda

Le funzioni lambda sono del codice che viene eseguito all’interno dell’infrastruttura AWS. Questo servizio gestisce automaticamente la fornitura e la gestione dei server sui quali viene eseguito il codice, compresa la scalabilità, il monitoraggio e il logging.

Le funzioni lambda possono essere sviluppate in Java, Python o NodeJS, nel nostro caso abbiamo scelto Python per via del suo basso footprint del codice. Le nostre funzioni vengono eseguite in risposta alle chiamate HTTP provenienti da attraverso API Gateway.

Le funzioni lambda sono adatte per esecuzioni di task medio/brevi, avendo esse un timeout massimo impostabile a 5 minuti, scaduto il quale l’infrastruttura termina forzatamente le istanze che le stanno eseguendo.

TIPS: Durante la fase di testing, prima del rilascio in produzione del progetto, abbiamo notato che in alcune situazioni i tempi di risposta risultavano poco efficienti . Da un’analisi approfondita abbiamo notato che questo accadeva solo nei momenti in cui non venivano fatte richieste al sistema per più di 5 minuti…il motivo è dovuto al fatto che, sotto il cofano di Lambda, vengono instanziati dei containers e quindi se le funzioni lambda non vengono eseguite frequentemente AWS libera le risorse per dedicarle ad altre. Quindi se passa troppo tempo è necessario attendere alla prima chiamata che venga ricreato l’ambiente per l’esecuzione del codice. Ovviamente, una volta passato in produzione, il problema non si è più presentato visto il numero di utenti a cui si rivolge il progetto. Vi consigliamo però, se utilizzate Lambda in sistemi con un volume di traffico minore in cui volete mantenere i tempi di risposta del servizio entro certi range, di creare delle chiamate periodiche per tenere allocate le risorse destinate all’esecuzione delle vostre lambda function.

DynamoDB

DynamoDB è un database NoSQL gestito da AWS e rappresenta una buona soluzione per architetture serverless in quanto l’unico aspetto da definire è il numero di letture e scritture al secondo che dovrà gestire.

Come tutti i database NoSQL, DynamoDB permette di memorizzare dei documenti a schema libero. Ogni tabella in DynamoDB ha un indice primario composto da una “partition key” che viene usata per suddividere i documenti in diverse partizioni, e una opzionale “sort key”, usata nelle query per effettuare un ordinamento. Ogni documento deve avere una coppia {“partition key”, “sort key”} univoca. È possibile definire altri indici con altre coppie {“partition key”, “sort key”}.

Durante la fase di progettazione dell’architettura siamo stati molto indecisi su quale Database NoSQL utilizzare, alla fine abbiamo scelto di utilizzare DynamoDB perchè, visto l’elevato numero di device che sarebbero stati coinvolti, era possibile scalare velocemente in termini di performance intervenendo nel numero di operazioni di lettura al secondo su ogni tabella, qualora fosse stato necessario nel caso in cui il dimensionamento iniziale fosse stato sottodimensionato e per l’alta disponibilità del servizio.

TIPS: A differenza di altri DB NoSQL, in DynamoDB le query possono essere eseguite solo su di un indice specificando la “partitio key”, quindi solo su di un sottoinsieme di documenti avente la stessa chiave. Mentre per una ricerca completa su di una tabella, l’unica opzione è la scansione completa non ordinata. Di conseguenza DynamoDB è particolarmente adatto per applicazioni di cui si conosce a priori la chiave primaria dei documenti da cercare, e meno adatto ad applicazioni tradizionali.

In questo progetto estremamente sfidante è stato possibile trarre il massimo vantaggio dall’impiego di tale nuovo paradigma di sviluppo che ci ha permesso di:

  • Focalizzare la nostra attenzione sullo sviluppo delle logiche di business
  • Dormire sonni tranquilli consapevoli del fatto che il sistema si sarebbe evoluto automaticamente in base al carico di lavoro, senza la necessità di nostri interventi
  • Sviluppare il codice in modo agile rilasciando velocemente funzioni lambda in base all’evoluzione del progetto.

In conclusione il paradigma di sviluppo tramite architetture Serverless, quando è possibile utilizzarlo, permette di demandare al Cloud provider molte delle responsabilità che sarebbero prima state a carico del nostro team.

Leave a Comment