Questo è il mio primo post sullo scambio di stack di Engineering Engineering, quindi fammi sapere se c'è qualcosa di sbagliato in questo.
Sto esaminando le offerte serverless di Amazon per cercare di capire se questa è la strada da percorrere per alcuni nuovi progetti che ho in mente. Sono particolarmente interessato a un modello CQRS basato sugli eventi, in quanto trovo molto interessanti i presunti vantaggi di tale modello in questo caso. Ma sto avendo un po 'di problemi a capire tutti i servizi che Amazon ha da offrire, quali sono i loro pro e contro e come si combinano tutti. Dopodiché darò un po 'di pretesto e in seguito dichiarerò le mie domande.
Userò un'applicazione di esempio per illustrare ciò che sto cercando:
È una semplice applicazione Web (statica), ospitata in S3 e pubblicata su cloudflare.
Ha due azioni: un comando e una query (in termini CQRS).
Il comando invia un evento sul flusso di eventi per incrementare un contatore.
La query ottiene lo stato corrente del contatore, cioè quante volte è stato incrementato.
Questo è tutto, quindi come posso implementarlo utilizzando la tecnologia AWS senza server? Ecco cosa sto pensando finora:
Per inviare il comando per incrementare il contatore, l'applicazione Web invia richieste AJAX a un lambda L1 (tramite un gateway API). Questo lambda L1 invia un evento al flusso di eventi.
Un altro lambda L2 ascolta il flusso di eventi e memorizza un record dell'evento / comando in modo che possa essere riprodotto in un secondo momento, se necessario.
Ancora un altro lambda L3 ascolta il flusso di eventi ed esegue il comando. In altre parole, recupera lo stato corrente del contatore, lo incrementa e persiste atomicamente nel nuovo stato.
Per inviare la query, l'applicazione Web invia una richiesta AJAX a lambda L4 (attraverso un gateway API), che interroga lo stato e restituisce il risultato.
Sembra che dovrebbe essere un progetto abbastanza semplice e minimale. Ecco le mie preoccupazioni finora:
Innanzitutto, quale dovrebbe essere il mio flusso di eventi? Ho visto molti suggerimenti fluttuare, ciascuno più contorto e inventato dell'ultimo. Varie strategie di smontaggio, mix di flussi SNS, SQS, Kinesis, DynamoDB, il tuo nome ... temo che finirò con troppe parti mobili, un sistema poco efficiente in termini di costi che è difficile scalare nel senso che la complessità rende è difficile da sviluppare per
In secondo luogo, posso ottenere l'atomicità? I servizi del flusso di eventi che ho menzionato sopra hanno in genere una sorta di proprietà "almeno una volta la consegna", che deve essere gestita dal consumatore. Un suggerimento che ho visto è quello di rendere ogni evento idempotente, ma ciò non sembra fattibile nella mia applicazione di esempio. Due client potrebbero incrementare il contatore allo stesso tempo e uno degli incrementi potrebbe essere "perso" perché entrambi i comandi direbbero "il contatore ora è 17 (ad esempio)". Si potrebbe argomentare che questo è un comportamento corretto, entrambi i client hanno visto il numero come 16 e hanno voluto incrementarlo a 17, ma diciamo in questa situazione che vorremmo che entrambi gli incrementi contassero verso il totale. Vogliamo che il nostro comando rappresenti solo un delta tra i due stati. C'è un modo per raggiungere questo obiettivo?
In terzo luogo, lambdas L3 e L4 devono essere entrambi in grado di accedere a una sorta di livello di persistenza. Idealmente mi piacerebbe che fosse un database relazionale (SQL) in modo da poter eseguire query avanzate sullo stato dell'applicazione corrente. Non è necessario per il mio esempio di contatore incrementale, ma sarà necessario per i progetti che ho in mente. Penso che questo mi lascia solo con una opzione se voglio rimanere senza server: Serverless Aurora. Per me va bene, ma è a mia conoscenza che Aurora ha bisogno di essere eseguito in un VPC e che lambda deve essere eseguito nello stesso VPC per avere accesso ad Aurora. Sono molto preoccupato per le prestazioni qui, poiché L3 è il singolo punto di congestione nel mio esempio (tutto il resto è solo accodamento o sola lettura). La mia comprensione è che i VPC comportano un costo considerevole delle prestazioni (throughput, numero di connessioni, larghezza di banda) e che lambdas nei VPC può avere avviamenti a freddo di oltre 10 secondi. Come posso affrontare questi problemi? Le campane d'allarme stanno andando nella mia testa, che questo introduce solo più problemi di quanti ne risolva. Probabilmente dovrei eseguire il ping di L4 continuamente in modo che non inizi mai a freddo (il tempo di caricamento di 10 secondi non è accettabile) ea quel punto, sto davvero andando senza server? Se questa è una cattiva idea, ci sono alternative migliori? Devo anche mantenere lo stato in DynamoDB, perdendo capacità di interrogazione?
Questo post è già piuttosto lungo, quindi per ora lascerò a questi tre problemi. Oltre a rispondere direttamente alle mie domande, se potessi aiutarmi a chiarire eventuali equivoci, offrire soluzioni alternative, ecc. Sarei grato!