Al giorno d'oggi, il servizio «Bitrix24» non dispone di centinaia di gigabit di traffico, né di un enorme parco server (anche se ce ne sono di esistenti, naturalmente). Ma per molti clienti è lo strumento principale di lavoro nell'azienda, è una vera applicazione business-critical. Pertanto, non ci si può permettere di cadere. E se una caduta si è comunque verificata, ma il servizio si è «rialzato» così rapidamente che nessuno se n'è accorto? E come si riesce a implementare il failover senza perdita di qualità del lavoro e numero di clienti? Alexander Demidov, direttore della direzione dei servizi cloud di «Bitrix24», ha parlato per il nostro blog di come nel corso di 7 anni di esistenza del prodotto sia evoluto il sistema di riserva.

«In formato SaaS abbiamo lanciato 'Bitrix24' 7 anni fa. La principale difficoltà, probabilmente, era la seguente: prima del lancio pubblico in formato SaaS, questo prodotto esisteva semplicemente come soluzione confezionata. I clienti lo acquistavano da noi, lo installavano sui propri server, creavano un portale aziendale - una soluzione comune per la comunicazione tra i dipendenti, la conservazione dei file, la gestione dei compiti, CRM, insomma, tutto questo. E nel 2012 abbiamo deciso di voler lanciare questo come SaaS, amministrando autonomamente, garantendo tolleranza ai guasti e affidabilità. Durante il processo abbiamo accumulato esperienza, perché fino a quel momento non ne avevamo - eravamo solo produttori di software, non fornitori di servizi.
Lanciando il servizio, sapevamo che la cosa più importante era garantire tolleranza ai guasti, affidabilità e disponibilità costante del servizio, perché se hai un semplice sito web, un negozio, ad esempio, e un giorno smette di funzionare per un'ora - ne soffri solo tu, perdi ordini, perdi clienti, ma per il tuo cliente non è molto critico. Certo, sarà deluso, ma andrà a comprare su un altro sito. Ma se si tratta di un'applicazione di cui dipende tutto il lavoro all'interno dell'azienda, comunicazioni e decisioni, la cosa più importante è guadagnare la fiducia degli utenti, cioè non deluderli e non andare in crash. Perché tutto il lavoro potrebbe fermarsi se qualcosa all'interno non funziona.
Bitrix24 come SaaS
Il primo prototipo lo abbiamo assemblato un anno prima del lancio pubblico, nel 2011. È stato assemblato in circa una settimana, lo abbiamo esaminato, girato — funzionava anche. Cioè, era possibile accedere al modulo, inserire lì il nome del portale, si apriva un nuovo portale, veniva creata una base di utenti. Lo abbiamo osservato, valutato sostanzialmente il prodotto, chiuso, e abbiamo continuato a lavorarci per un intero anno. Perché avevamo un grande compito: non volevamo creare due basi di codice differenti, non volevamo supportare separatamente un prodotto confezionato e soluzioni cloud, — volevamo fare tutto questo all'interno di un unico codice.

Un'app web tipica all'epoca era un server su cui girava un qualche codice php, un database mysql, i file venivano caricati, i documenti, le immagini venivano messi nella cartella upload – e tutto questo funzionava. Purtroppo, non è possibile avviare un servizio web critico su questo. Non viene supportata la cache distribuita, la replica dei database non è supportata.
Abbiamo formulato i requisiti: la capacità di essere ospitati in diverse località, supportare la replica, idealmente essere ospitati in diversi data center geograficamente distribuiti. Separare la logica del prodotto e, appunto, lo storage dei dati. Essere in grado di scalare dinamicamente in base al carico, spostare completamente la parte statica. Da queste considerazioni si sono formati, sostanzialmente, i requisiti per il prodotto, che abbiamo elaborato nel corso dell'anno. In questo periodo, nella piattaforma, che è diventata unitaria — per le soluzioni confezionate, per il nostro servizio — abbiamo implementato il supporto per le cose di cui avevamo bisogno. Supporto per la replicazione mysql a livello di prodotto: cioè, lo sviluppatore che scrive codice — non si preoccupa di come saranno distribuite le sue richieste, utilizza la nostra api, e noi sappiamo distribuire correttamente le richieste di scrittura e lettura tra master e slave.
Abbiamo creato supporto a livello di prodotto per vari storage oggetti nel cloud: google storage, amazon s3, — inoltre, supporto open stack swift. Pertanto, è stato conveniente sia per noi come servizio, sia per gli sviluppatori che lavorano con la soluzione confezionata: se utilizzano semplicemente la nostra api per lavorare, non si preoccupano di dove alla fine verrà salvato il file, se localmente nel file system o se finirà nello storage di oggetti.
Alla fine abbiamo subito deciso che ci saremmo riservati a livello di intero data center. Nel 2012 ci siamo lanciati completamente su Amazon AWS, perché avevamo già esperienza con questa piattaforma, essendo il nostro sito già ospitato lì. Ci attraeva il fatto che in ogni regione di Amazon ci sono più zone di disponibilità — in sostanza, (nella loro terminologia) diversi data center che sono più o meno indipendenti l'uno dall'altro e ci permettono di riservarci a livello di intero data center: se uno di essi dovesse guastarsi, i database si replicano in modalità master-master, i server delle applicazioni web sono riservati e la staticità è trasferita nell'archiviazione a oggetti s3. Il carico è bilanciato — in quel momento da elb di Amazon, ma poco dopo siamo passati ai nostri bilanciatore, perché avevamo bisogno di una logica più complessa.
Quel che volevamo, l'abbiamo ottenuto...
Tutte le cose di base che volevamo garantire — l'affidabilità dei server stessi, delle applicazioni web, dei database — funzionavano bene. Lo scenario più semplice: se una delle nostre applicazioni web smette di funzionare, qui tutto è semplice — vengono esclusi dal bilanciamento.

Le macchine guaste venivano contrassegnate come non funzionanti dal bilanciatore (all'epoca era l'elb di Amazon), il quale smetteva di distribuire il carico su di esse. Funzionava l'auto-scalaggio di Amazon: quando il carico aumentava, nuove macchine venivano aggiunte al gruppo di auto-scalaggio, il carico veniva distribuito su nuove macchine — tutto andava bene. Con i nostri bilanciatore la logica è approssimativamente la stessa: se succede qualcosa a un server delle applicazioni, rimuoviamo le richieste, scartiamo queste macchine, avviamo di nuove e continuiamo a lavorare. La схема è cambiata un po' nel corso degli anni, ma continua a funzionare: è semplice, comprensibile e non ci sono complessità.
Lavoriamo in tutto il mondo, i picchi di carico dei clienti sono assolutamente diversi, e, in pratica, dovremmo avere la possibilità di effettuare alcuni lavori di manutenzione su qualsiasi componente del nostro sistema in qualsiasi momento – senza che i clienti se ne accorgano. Pertanto, abbiamo la possibilità di disattivare il database, redistribuendo il carico su un secondo data center.
Come funziona tutto questo? — Reindirizziamo il traffico su un data center funzionante: se si tratta di un incidente nel data center, lo facciamo completamente. Se sono lavori pianificati su un particolare database, reindirizziamo solo una parte del traffico che serve quei clienti su un secondo data center, interrompendo la replicazione. Se servono nuove macchine per le applicazioni web, poiché il carico è aumentato nel secondo data center, queste si avviano automaticamente. Concludiamo i lavori, ripristiniamo la replicazione e riportiamo tutto il carico indietro. Se dobbiamo eseguire dei lavori speculari nel secondo DC, ad esempio installare aggiornamenti di sistema o modificare le impostazioni nel secondo database, in sostanza ripetiamo tutto lo stesso, ma al contrario. In caso di incidente, seguiamo una procedura semplice: nel sistema di monitoraggio utilizziamo il meccanismo degli event-handler. Se più controlli vengono attivati e lo stato passa a critico, avviamo questo handler, un elaboratore che può eseguire una logica specifica. Abbiamo definito per ogni database quale server è il suo failover e dove reindirizzare il traffico in caso di inaccessibilità. Storicamente, utilizziamo nagios o alcuni dei suoi fork. In genere, meccanismi simili sono presenti praticamente in ogni sistema di monitoraggio; finora non utilizziamo nulla di più complesso, ma potrebbe succedere in futuro. Attualmente, il monitoraggio attiva in caso di inaccessibilità e ha la possibilità di reindirizzare il traffico.
Abbiamo riservato tutto?
Abbiamo molti clienti negli Stati Uniti, molti clienti in Europa e molti clienti più vicini all'Oriente, come Giappone, Singapore e così via. Naturalmente, una parte significativa dei clienti si trova in Russia. Questo significa che lavoriamo in più di una regione. Gli utenti desiderano risposte rapide, ci sono requisiti per il rispetto di diverse leggi locali e all'interno di ogni regione riserviamo due data center, oltre ad avere alcuni servizi aggiuntivi che è comodo collocare all'interno di una sola regione per i clienti che operano in quella regione. I gestori REST e i server di autorizzazione sono meno critici per il funzionamento generale del cliente; si può passare a loro con un certo ritardo accettabile, ma non vogliamo reinventare la ruota, monitorandoli e decidendo cosa fare con loro. Pertanto, cerchiamo di usare il più possibile soluzioni già esistenti, piuttosto che sviluppare competenze interne su prodotti aggiuntivi. In alcune situazioni, utilizziamo semplicemente il passaggio a livello DNS, e la disponibilità del servizio viene definita dallo stesso DNS. In Amazon c'è il servizio Route 53, ma non è solo un DNS in cui è possibile inserire record e basta; è molto più flessibile e conveniente. Attraverso di esso, è possibile costruire servizi geo-distribuiti con geolocalizzazioni, quando si determina da dove proviene il cliente e si offrono i vari record; è possibile costruire architetture di failover. Gli stessi health-checks sono impostati all'interno di Route 53, si definisce l'endpoint da monitorare, le metriche da utilizzare e i protocolli per determinare se il servizio è “vivo” o meno: tcp, http, https; si definisce la periodicità dei controlli per stabilire se il servizio è attivo o meno. E nel DNS si specifica quale sarà il primary, quale sarà il secondary e dove passare se il health-check all'interno di Route 53 si attiva. Tutto questo può essere realizzato con altri strumenti, ma la comodità è che lo si configura una volta e poi non si deve più pensare a come vengono eseguiti i controlli o come avviene il passaggio: tutto funziona in automatico.
Il primo "ma": e come e con cosa riservare il route 53? Non si sa mai, potrebbe succedere qualcosa! Fortunatamente, non ci siamo mai trovati in questa situazione, ma a breve vi racconterò perché abbiamo ritenuto necessario avere una riserva. Qui ci prepariamo in anticipo. Alcune volte al giorno, facciamo un’estrazione completa di tutte le zone che abbiamo attivate su route 53. L'API di Amazon permette di restituirle facilmente in JSON, e abbiamo attivato diversi server di riserva dove le convertiamo, le estraiamo sotto forma di configurazioni e, in termini semplici, abbiamo una configurazione di backup. In caso di necessità, possiamo rilasciarla rapidamente a mano, senza perdere i dati delle impostazioni DNS.
Il secondo "ma": cosa non è ancora riservato in questo scenario? Il bilanciatore stesso! La nostra distribuzione dei clienti per regioni è molto semplice. Abbiamo i domini bitrix24.ru, bitrix24.com, .de — ora sono circa 13 diversi, che operano in varie zone. Siamo giunti alla seguente conclusione: in ogni regione ci sono i propri bilanciatori. È più conveniente distribuirli per regioni, a seconda di dove si trova il picco di carico di rete. Se c'è un guasto a livello di un singolo bilanciatore, lo si esclude semplicemente dal funzionamento e lo si rimuove dal DNS. Se si verifica un problema con un gruppo di bilanciatori, vengono riservati su altre piattaforme e il passaggio tra di essi avviene tramite route53, poiché grazie a un TTL breve il cambio avviene al massimo in 2, 3, 5 minuti.
Il terzo "ma": cosa non è ancora riservato? S3, giusto. Noi, mentre archiviavamo i file che conserviamo per gli utenti su S3, eravamo convinti che fosse infallibile e che non ci fosse bisogno di riservare nulla. Ma la storia dimostra che le cose vanno diversamente. In generale, Amazon descrive S3 come un servizio fondamentale, perché Amazon stesso utilizza S3 per memorizzare le immagini delle macchine, le configurazioni, le immagini AMI, gli snapshot… E se S3 si guasta, come è successo una volta in questi 7 anni in cui abbiamo utilizzato bitrix24, porta con sé una moltitudine di problemi: l’indisponibilità dell’avvio delle macchine virtuali, guasti nel funzionamento dell'API e così via.
E S3 può cadere — è successo una volta. Pertanto, siamo giunti al seguente schema: qualche anno fa, in Russia non c'erano pubblici storage oggettivi seri, e stavamo considerando l'idea di creare qualcosa di nostro... Per fortuna non abbiamo iniziato a farlo, perché ci saremmo impantanati in quella expertise che non possediamo, e probabilmente avremmo sbagliato. Ora ci sono storage compatibili con s3 di Mail.ru, di Yandex e di altri fornitori. Alla fine, siamo giunti alla conclusione che vogliamo avere, in primo luogo, un sistema di riserva e, in secondo luogo, la possibilità di lavorare con copie locali. Per la specifica regione russa, utilizziamo il servizio Mail.ru Hotbox, che è compatibile con s3 tramite l'api. Non ci sono serviti grossi adattamenti al codice all'interno dell'applicazione e abbiamo creato il seguente meccanismo: in s3 ci sono trigger che si attivano alla creazione/rimozione di oggetti, Amazon ha un servizio del tipo Lambda — è un'esecuzione serverless di codice che verrà eseguita proprio all'attivazione di quei trigger.

Abbiamo fatto tutto molto semplicemente: se un trigger viene attivato, eseguiamo un codice che copia l'oggetto nello storage di Mail.ru. Per avviare correttamente il lavoro con le copie locali dei dati, abbiamo bisogno anche di una sincronizzazione inversa, affinché i clienti nel segmento russo possano lavorare con uno storage a loro più vicino. Mail sta per completare i trigger nel proprio storage — sarà possibile già a livello infrastrutturale eseguire la sincronizzazione inversa, nel frattempo lo facciamo a livello del nostro codice. Se vediamo che un cliente ha caricato un file, mettiamo un evento nella coda a livello di codice, lo elaboriamo e facciamo una replica inversa. Qual è il problema: se svolgiamo qualche lavoro con i nostri oggetti al di fuori del nostro prodotto, cioè con strumenti esterni, non lo considereremo. Pertanto, stiamo aspettando fino a quando non appariranno i trigger a livello di storage, affinché, indipendentemente da dove eseguiamo il codice, l'oggetto che ci raggiunge venga copiato nella direzione opposta.
A livello di codice, per ciascun cliente definiamo entrambi gli archivi: uno è considerato principale, l'altro di backup. Se tutto funziona correttamente, lavoriamo con l'archivio che ci è più vicino: i nostri clienti in Amazon utilizzano S3, mentre quelli in Russia usano Hotbox. Se scatta un flag, dobbiamo attivare il failover e trasferire i clienti a un altro archivio. Possiamo impostare questo flag indipendentemente per regione e possiamo fare cambiamenti. In pratica non ne abbiamo ancora avuto bisogno, ma abbiamo previsto questo meccanismo e crediamo che prima o poi ci servirà questo cambio. È già successo una volta.
Oh, ma il vostro Amazon è scappato...
Questo aprile segna l'anniversario dell'inizio del blocco di Telegram in Russia. Il provider più colpito da questa situazione è stato Amazon. Sfortunatamente, le aziende russe che operano a livello globale hanno subito maggiori danni.
Se l'azienda è globale e la Russia rappresenta solo un piccolo segmento, 3-5% — in un modo o nell'altro, si possono sacrificare.
Se si tratta di un'azienda puramente russa, sono certo che è necessario operare localmente — sarebbe più comodo e sicuro per gli utenti stessi.
E se si tratta di un'azienda che opera a livello globale e ha un numero simile di clienti russi e nel resto del mondo? La connessione tra i segmenti è importante, e devono lavorare insieme in un modo o nell'altro.
Alla fine di marzo 2018, Roskomnadzor ha inviato una lettera ai maggiori operatori, informandoli che pianificano di bloccare milioni di indirizzi IP di Amazon per bloccare… il messenger Zello. Grazie a questi provider, sono riusciti a diffondere la lettera, e si è compresa la possibilità che la connessione con Amazon potesse interrompersi. Era venerdì, e in preda al panico ci siamo affrettati dai colleghi di servers.ru, dicendo: «Amici, abbiamo bisogno di alcuni server che non siano in Russia, non in Amazon, ma ad esempio ad Amsterdam», per poter avere almeno un modo per mettere lì i nostri vpn e proxy per alcuni endpoint, sui quali non possiamo influire in alcun modo, ad esempio gli endpoint dello stesso s3 — non possiamo provare a creare un nuovo servizio e ottenere un altro IP, dobbiamo comunque raggiungerli. In pochi giorni abbiamo configurato questi server, li abbiamo attivati e, in generale, ci siamo preparati per l'inizio dei blocchi. Curiosamente, il RKN, dopo aver osservato il trambusto e il panico sollevato, ha detto: «No, adesso non bloccheremo nulla». (Ma questo è stato proprio fino al momento in cui hanno iniziato a bloccare Telegram.) Configurando le possibilità di bypassare e comprendendo che il blocco non è stato attuato, non ci siamo comunque messi a smontare tutto. Per ogni evenienza.

E così, nel 2019 viviamo chiaramente in un contesto di blocchi. Ieri notte stavo osservando: circa un milione di IP continuano a essere bloccati. In verità, Amazon è stato quasi interamente sbloccato, e ai picchi si arrivava a 20 milioni di indirizzi... In generale, la realtà è che la connettività, una buona connettività — potrebbe non esserci. All'improvviso. Potrebbe non esserci per motivi tecnici — incendi, escavatori, tutto il resto. Oppure, come abbiamo visto, non proprio per motivi tecnici. Pertanto, qualcuno grande e importante, con propri AS, probabilmente può gestire la situazione in altri modi — direct connect e altre cose già a livello l2. Ma nel semplice caso, come noi o altre aziende più piccole, è utile avere delle riserve a livello di server, attivati altrove, configurati in anticipo con VPN, proxy, con la possibilità di switchare rapidamente la configurazione in quei segmenti critici per la connettività. Questo ci è stato utile più volte quando sono iniziati i blocchi su Amazon, utilizzavamo per lo più il traffico S3, ma lentamente tutto si è sistemato.
E come riservare... un intero provider?
Attualmente non abbiamo uno scenario per un guasto totale di Amazon. Abbiamo uno scenario simile per la Russia. In Russia ci siamo appoggiati a un fornitore, da cui abbiamo scelto di avere diverse sedi. Un anno fa ci siamo imbattuti in un problema: anche se ci sono due data center, già a livello di configurazione di rete del fornitore possono verificarsi problemi che colpiscono entrambi i data center. E possiamo avere downtime in entrambe le sedi. Naturalmente, è proprio quello che è successo. In definitiva, abbiamo rivisto l'architettura interna. Non è cambiata molto, ma per la Russia ora abbiamo due sedi, che non sono dello stesso fornitore, ma di due diversi. Se uno avesse un guasto, possiamo passare all'altro.
Ipoteticamente stiamo considerando per Amazon la possibilità di riservare a livello di un altro fornitore; forse Google, forse qualcun altro... Ma finora abbiamo visto nella pratica che se ci sono problemi su un'area di disponibilità di Amazon, i guasti a livello di un'intera regione sono abbastanza rari. Pertanto, teoricamente abbiamo un'idea di farlo come riservazione "Amazon - non Amazon", ma nella pratica ciò non è ancora avvenuto.
Qualche parola sull'automazione
L'automazione è sempre necessaria? Qui è opportuno ricordare l'effetto Dunning-Kruger. Sull'asse "x" ci sono le nostre conoscenze e l'esperienza che acquisiremo, e sull'asse "y" — la fiducia nelle nostre azioni. All'inizio non sappiamo nulla e non siamo affatto sicuri. Poi sappiamo un po' e diventiamo super sicuri: questo è il cosiddetto "picco dell'ignoranza", ben illustrato dall'immagine "follia e coraggio". Successivamente, abbiamo già imparato un po' e siamo pronti a combattere. Poi inciampiamo in qualche grave insidia e cadiamo nella valle della disperazione, quando sembra che sappiamo qualcosa, ma in realtà non sappiamo molto. Poi, man mano che accumuliamo esperienza, diventiamo più sicuri.

La nostra logica riguardo ai vari passaggi automatici per diverse emergenze è ben descritta da questo grafico. Siamo partiti da zero — non sapevamo fare nulla, praticamente tutto era eseguito manualmente. Poi abbiamo capito che potevamo automatizzare tutto e, in un certo senso, stare tranquilli. Ma all'improvviso ci siamo trovati di fronte a grosse complicazioni: abbiamo ricevuto un falso positivo e ci siamo trovati a spostare il traffico da una parte all'altra, quando, a dire il vero, non sarebbe stato necessario. Di conseguenza, la replicazione si interrompe o qualcosa del genere — ecco la famosa valle dell'angoscia. Poi abbiamo capito che bisogna affrontare tutto con discernimento. Questo significa che ha senso affidarsi all'automazione, prevedendo la possibilità di falsi allarmi. Ma! se le conseguenze possono essere devastanti, è meglio lasciare la gestione a un turno di guardia, a ingegneri di turno, che verificheranno, controlleranno che ci sia realmente un'emergenza e che le azioni necessarie vengano eseguite manualmente...
Conclusione
In 7 anni siamo passati da una situazione in cui, quando qualcosa andava in crisi, c'era panico totale, alla consapevolezza che non esistono problemi, solo compiti che devono essere — e possono essere — risolti. Quando costruite un servizio, osservatelo dall'alto, valutate tutti i rischi potenziali. Se li vedete subito — prevedete in anticipo il back-up e la possibilità di costruire un'infrastruttura resistente ai guasti, perché qualsiasi punto che può guastarsi e causare l'inefficienza del servizio — lo farà sicuramente. E anche se vi sembra che alcuni elementi dell'infrastruttura non possano guastarsi — come lo s3, ricordate comunque che è possibile. E quantomeno in teoria, siate pronti a sapere cosa fare con loro se qualcosa dovesse succedere. Avete un piano per gestire i rischi. Quando vi preparate a fare tutto in automatico o manualmente, valutate i rischi: cosa succederà se l'automazione inizia a fare cambiamenti — porterà a una situazione ancora peggiore rispetto a quella di emergenza? Potrebbe essere necessario trovare un compromesso ragionevole tra l'uso dell'automazione e la reazione di un ingegnere di turno, che valuterà la situazione reale e deciderà se è necessario cambiare qualcosa immediatamente o
Un compromesso ragionevole tra perfezionismo e le reali forze, tempo e denaro che puoi investire nello schema che avrai alla fine.
Questo testo è una versione ampliata e arricchita della relazione di Aleksandr Demidov alla conferenza .
Fonte: habr.com
