Sistemi in load balancing su Amazon per l’eshop di Alcott & Alcott Los Angeles
Oggi (20 maggio 2015) è andato online l’eshop di ALCOTT & ALCOTT LOS ANGELES realizzato dalla 3d0 usando come base le mie librerie eStore nella versione 6.1.
La richiesta iniziale del cliente era di realizzare uno shop con Magento, ma la poca reattività e la grossa mole di traffico prevista ha spinto la 3d0 a consigliare al cliente l’utilizzo di una piattaforma proprietaria ben conosciuta e più performante; la scelta, come mostrerò a breve, si è rivelata vincente.
Per l’installazione e la manutenzione dei sistemi la 3d0 si è rivolta a noi di Livecode con delle richieste ben precise:
- setup di tutti i sistemi su Amazon Web Services
- sistema autoscalante per far fronte a traffico non prevedibile a priori
- sistemi ridondati
- backup periodici
- load balancer
in più io ho consigliato l’utilizzo di un CDN (Content Delivery Network) di cui siamo partner, CloudFlare, per ridurre il carico sulle macchine.
Il sito web è stato sviluppato in tempo record con parecchie funzioni custom realizzate ad hoc per il cliente, e si è decisa come data di lancio il 20/05/2015 alle ore 10:00.
Dal punto di vista dei sistemi le sfide erano l’alta disponibilità e il load balancing senza dover fare modifiche al software, ma agendo unicamente sui server. In questo modo i programmatori non avrebbero dovuto preoccuparsi della piattaforma ma solo del software.
L’eshop è stato infatti inizialmente sviluppato su uno dei server 3d0 in housing presso di noi nel nostro Datacenter del Centro Direzionale di Napoli. Un paio di settimane prima del lancio ho preparato i sistemi su AWS e ho spostato tutti i dati sul webserver di prova e, una volta confermato il buon funzionamento del sistema, ho generato un’immagine che sarebbe servita per l’autoscaler.
L’idea iniziale per lo storage dei file (immagini, documenti, risorse statiche) era di usare Amazon Simple Storage Service (S3) ma questo avrebbe richiesto sia delle modifiche alle funzioni di gestione del filesystem sia alle procedure già in uso dai grafici e dai programmatori. Ho quindi deciso di usare uno storage ridondato da far montare in NFS ai webserver. Come base ho usato openSUSE e SLES.
Il primo passo per creare la struttura è attivare una mia AWS VPC (Virtual Private Cloud) in EU-WEST-1, con dei range IP privati per me facili da ricordare e che non andassero in conflitto con quelli che già uso altrove. Decido per una /22 (1024 ip) che suddividerò in varie /24 (256 ip), una per availability zone (AZ).
Come macchine di storage decido per delle t2.medium, l’AZ è EU-WEST-1a (Irlanda), per i dati uso due volumi EBS da 200GB ridondati in DRBD Primary/Primary e file system OCFS2.
La partizione viene esportata in NFS4 per le classi ip della Livecode (siamo LIR – IT.LIVECODE) e per le classi interne della VPC.
Impostato lo storage, passo ad attivare il db. Il mio eStore usa come database PostgreSQL perché quando l’ho iniziato il mySQL era tutto fuorché stabile sotto grossi carichi e successivamente non ho trovato motivi validi per cambiare. Attivo quindi un’istanza di Amazon Relational Database (RDS) per PostgreSQL. RDS è molto comodo: si tratta in sostanza di una macchina EC2 con il DB engine scelto, già configurata e a cui si può accedere solo via database.
E’ possibile anche richiederla in configurazione Multi-AZ. In questo caso Amazon attiva due macchine identiche in replica e se una delle due ha problemi il servizio viene dirottato sull’altra senza che il sistema soffra di interruzioni.
All’inizio ho utilizzato una db.m3.large; dopo il lancio ci siamo resi conto che la CPU della macchina RDS aveva un carico troppo alto e l’abbiamo convertita in db.m3.xlarge. Una delle comodità di RDS è che è possibile modificare on the fly il tipo di macchina, alcuni parametri di configurazione e il multizona senza dover riavviare.
Il passo successivo è stato ovviamente configurare i webserver. Ho preparato una macchina con PHP+Apache usando un’istanza r3.large (anche questa poi modificata in c3.xlarge), ho fatto tutti gli aggiornamenti necessari e le configurazioni utili al ricreare l’ambiente di sviluppo e infine ho rilasciato il sistema ai programmatori di 3d0.
Una volta avuta la conferma che il sistema fosse adatto al funzionamento del sito ho creato una Amazon Machine Images (AMI), cioè un’immagine del webserver. Questo passaggio è molto importante perché ci consente di poter successivamente creare quante macchine vogliamo, identiche alla prima. Qui ho fatto un piccolo errore… quando ho creato la AMI c’era un messaggio nella coda di Postfix e quindi ogni volta che genero una nuova macchina questo messaggio di posta viene inviato. Scusa Antonio, provvederò quanto prima al reimaging 🙂
Dalla AMI ho lanciato una nuova istanza che è partita senza problemi, tra Livecode e 3d0 abbiamo fatto tutti i test necessari e abbiamo concordato che era tutto ok.
Per soddisfare le esigenze di traffico non prevedibile, ho utilizzato le funzioni native di EC2 di Auto Scaling. Ho creato una configurazione di lancio indicando il tipo di istanza, l’AZ, lo storage, la VPC e così via. La configurazione di lancio è un ‘template’ che viene utilizzato per avviare nuove istanze.
Ho poi attivato un Elastic Load Balancer, molto semplicemente un reverse proxy che riceve le richieste e le gira ai webserver che ci sono dietro. Ha un sistema di sanity check integrato (configurabile) che controlla che le macchine siano effettivamente vive prima di collegarle al load balancer e se è eventualmente necessario disattivarle.
L’ultimo passaggio su AWS è stato la creazione di un Auto Scaling Group. Ho scelto la configurazione di lancio (quella creata prima), il numero di istanze minimo e massimo (minimo un’istanza sempre attiva, massimo 5) e i parametri secondo cui decidere se lanciare una nuova istanza, se disattivarla e quale disattivare. In questo caso i parametri sono relativi alla CPU: se l’occupazione media supera un certo valore va avviata una nuova istanza, se scende sotto un certo valore l’istanza più recente va terminata.
Attenzione: per Amazon ‘spegnere’ e ‘terminare’ non sono equivalenti. Una macchina ‘spenta’ costa comunque per lo spazio che occupano i suoi dischi, una macchina ‘terminata’ viene proprio eliminata dall’account.
Qualche ora prima del lancio abbiamo modificato i nameserver per puntare al load balancer e alle 10.00 in punto è stata tolta la configurazione verso la pagina di cortesia e attivato il sito.
Che, per poco, non è soffocato sotto le richieste in arrivo 🙂
Le 5 macchine previste sono risultate poche per il numero di visitatori!
Qui mi è venuto immediatamente in soccorso uno strumento utilissimo di AWS: lancia più macchine come questa.
In questo modo ho immediatamente lanciato altre macchine identiche a quelle già in uso e le ho collegate al load balancer; in pochi minuti il traffico era sotto controllo e il sito navigabile velocemente. In totale, per gestire il lancio, ci sono volute dodici macchine, tra le 5 dell’autoscaler e 7 lanciate a mano. Nel pomeriggio la situazione si è normalizzata e ho disattivato le 7 macchine aggiuntive mentre, in serata, l’autoscaler ha iniziato a ridurre le sue macchine fino ad averne attive, in media, 2. Ora il traffico è nella norma e l’autoscaler (riconfigurato per lanciare fino a 10 macchine in caso di necessità) sta facendo egregiamente il suo lavoro.
Un ultimo dato interessante: nelle 14 ore del giorno del lancio, il sito ha consumato quasi 140 gigabyte di traffico, di cui oltre il 90% è stato servito dalla CDN di CloudFlare.
Ora i sistemi sono sotto osservazione per controllare che tutto funzioni bene.
In conclusione? Se avete bisogno di un’infrastruttura ridondata e autoscalante Amazon AWS fa sicuramente al caso vostro!
Se avete voglia di approfondire questo argomento o volete dei chiarimenti su quanto scritto in quest’articolo non esitate a contattarmi via email, Facebook o LinkedIn!