Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Il direttore per l'esercizio del portale Banki.ru, Andrey Nikol'skiy, ha parlato alla conferenza dello scorso anno DevOpsDays Moscow sui servizi orfani: come riconoscere un orfano nell'infrastruttura, quali problemi comportano i servizi orfani, cosa fare con loro e come procedere se niente funziona.

Sotto il post troverete la versione testuale della relazione.

Guarda il video

Salve, colleghi! Mi chiamo Andrey, e sono responsabile dell'esercizio presso Banki.ru.

Abbiamo grandi servizi, che sono dei monoliti, abbiamo servizi in un'accezione più classica e abbiamo anche servizi molto piccoli. Nella mia terminologia da lavoratore, dico che se un servizio è semplice e piccolo, allora è micro, e se non è molto semplice e non è piccolo, allora è semplicemente un servizio.

Vantaggi dei servizi

Passerò rapidamente sui vantaggi dei servizi.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Primo — scalabilità. Puoi rapidamente realizzare qualcosa su un servizio e lanciarlo in produzione. Ti arriva del traffico, quindi cloni il servizio. Ti arriva altro traffico, clonano di nuovo e con questo vivi. Questo è un buon bonus e, fondamentalmente, quando abbiamo iniziato, era considerato il nostro motivo principale per fare tutto questo.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

In secondo luogo, sviluppo isolato, quando hai più squadre di sviluppo, diversi sviluppatori in ogni squadra, e ciascuna squadra sviluppa il proprio servizio.

Con le squadre ci sono delle sfide. Gli sviluppatori possono essere diversi. E esistono, ad esempio, persone-fiocco di neve. L'ho visto per la prima volta da Maksim Dorofeev. A volte ci sono persone-fiocco di neve in alcune squadre, e in altre no. Questo rende i diversi servizi utilizzati nell'azienda un po' disomogenei.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Guarda l'immagine: questo è un buon sviluppatore, ha grandi mani, può fare molte cose. Il problema principale è da dove provengono queste mani.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

I servizi offrono la possibilità di utilizzare diversi linguaggi di programmazione, più adatti a compiti diversi. Alcuni servizi sono in Go, altri in Erlang, altri in Ruby, alcuni in PHP, altri in Python. In generale, si può spaziare molto. Anche qui ci sono delle sfide.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

L'architettura orientata ai servizi riguarda soprattutto il devops. Quindi, se non hai automazione, non hai un processo di deployment, se configuri manualmente, le tue configurazioni possono variare da un'istanza all'altra del servizio, e devi andare a fare qualcosa, allora sei nei guai.

Ad esempio, hai 20 servizi e devi fare il deployment manualmente, hai 20 console e premi «enter» simultaneamente come un ninja. Non è un buon modo di lavorare.

Se hai un servizio dopo il collaudo (se c'è collaudo, naturalmente) e devi ancora rifinirlo affinché funzioni in produzione, ho anche per te brutte notizie.

Se ti affidi a servizi specifici di Amazon e lavori in Russia, due mesi fa anche tu avevi «Tutto intorno brucia, sto bene, tutto è fantastico».

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Noi utilizziamo Ansible per automatizzare il deployment, Puppet per la convergenza, Bamboo per l'automazione del deployment, Confluence per descrivere tutto ciò in qualche modo.

Non mi fermerò a questo in dettaglio, perché la presentazione riguarda più le pratiche di interazione che non la realizzazione tecnica.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Avevamo, ad esempio, problemi in cui Puppet sul server funziona con Ruby 2, mentre un'applicazione è scritta per Ruby 1.8 e insieme non funzionano. Lì si verifica qualche problema. E quando devi mantenere diverse versioni di Ruby su una sola macchina, di solito sorgono problemi.

Noi, ad esempio, forniamo a ogni sviluppatore un ambiente, dove c'è circa tutto ciò che abbiamo, tutti i servizi che possono essere sviluppati, in modo che abbia un ambiente isolato dove può distruggerlo e costruirlo come vuole.

A volte è necessario un pacchetto compilato appositamente con supporto per qualcosa. È abbastanza rigoroso. Ho ascoltato una presentazione in cui l'immagine Docker pesa 45 GB. In Linux, ovviamente, è più semplice, tutto è più leggero, ma comunque non ci sarà mai abbastanza spazio.

E ci sono dipendenze contraddittorie, quando un pezzo del progetto dipende da una versione di una libreria, e un altro pezzo del progetto da un'altra versione, e le librerie non possono essere installate insieme in alcun modo.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Abbiamo siti e servizi su PHP 5.6, di cui ci vergogniamo, ma che ci possiamo fare. Questa è una nostra piattaforma. Ci sono siti e servizi su PHP 7, ce ne sono di più e per quelli non ci vergogniamo. E ogni sviluppatore ha il suo database, dove lavora felicemente.

Se scrivi in azienda in un'unica lingua, avere tre macchine virtuali per sviluppatore suona normale. Se hai diversi linguaggi di programmazione, la situazione peggiora.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Emergono siti e servizi su questo, su questo, poi un'altra piattaforma per Go, una piattaforma per Ruby, e un Redis a fianco. Alla fine, tutto ciò si trasforma in un grande campo di supporto, e c'è sempre qualcosa che può rompersi.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Per questo motivo, abbiamo sostituito i vantaggi del linguaggio di programmazione con l’uso di diversi framework, poiché i framework su PHP sono abbastanza diversi, hanno diverse capacità, diverse comunità e supporto. E si può scrivere un servizio in modo che ci sia già qualcosa di pronto per esso.

Ogni servizio ha il proprio team

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Il nostro principale vantaggio, che si è cristallizzato nel corso degli anni, è che ogni servizio ha il proprio team. Questo è utile per un grande progetto, permette di risparmiare tempo nella documentazione, i manager conoscono bene il loro progetto.

I compiti di supporto possono essere gestiti facilmente. Ad esempio, se un servizio di assicurazione si rompe. E subito il team che si occupa dell'assicurazione va a ripararlo.

Si possono realizzare rapidamente nuove funzionalità, perché quando hai un servizio atomico, puoi facilmente integrare qualcosa.

E quando hai rotto il tuo servizio, ed è inevitabile che accada, non danneggi gli altri servizi, e gli sviluppatori delle altre squadre non vengono da te con i bastoni dicendo: «Oh no, non farlo».

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Come sempre, ci sono delle sfumature. Abbiamo team stabili, i manager sono ben ancorati ai team. Ci sono documenti chiari e i manager controllano attentamente tutto. Ogni team ha diversi servizi insieme al manager, e c'è un punto di competenza specifico.

Se i team sono fluttuanti (anche questo avviene di tanto in tanto), c'è un buon metodo, chiamato 'mappa stellare'.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Hai una lista di servizi e di persone. Una stellina significa che la persona è un esperto in quel servizio, un libro significa che la persona sta studiando quel servizio. Il compito della persona è quello di cambiare il libro in stellina. E se non è scritto nulla di fronte al servizio, iniziano i problemi, di cui parlerò più avanti.

Come nascono i servizi orfani?

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Il primo problema, il primo modo per avere un servizio orfano nella propria infrastruttura è il licenziamento delle persone. A qualcuno è mai capitato che dall'azienda arrivassero scadenze prima di aver valutato i compiti? A volte le scadenze sono rigide e non c'è tempo per la documentazione. «Devi consegnare il servizio in produzione, poi lo completiamo».

Se il team è piccolo, può capitare che ci sia un solo sviluppatore che scrive tutto, mentre gli altri sono di supporto. «Ho scritto l'architettura principale, tu inizia a gettare le basi delle interfacce». Poi a un certo punto il manager, ad esempio, se ne va. E in quel periodo, quando il manager se ne è andato e non è ancora stato nominato un nuovo, gli sviluppatori decidono da soli quale direzione prendere per il servizio, cosa succede. E come sappiamo (torniamo indietro di alcuni slide), in alcuni team ci sono persone-uniche, a volte un leader unico. Poi si dimette e otteniamo un servizio orfano.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Nel frattempo, i compiti del supporto e dell'azienda non svaniscono, si accumulano nel backlog. Se durante lo sviluppo del servizio ci sono stati errori architetturali, anche questi si accumulano nel backlog. Il servizio degrada lentamente.

Come identificare un orfano?

Questa lista descrive bene la situazione. Chi ha riconosciuto qualcosa nella propria infrastruttura?

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Sui work-around documentati: c'è un servizio che, in generale, funziona, ha un manuale di due pagine su come usarlo, ma come funziona internamente nessuno lo sa.

O, per esempio, c'è un qualche accorciatore di link. Per noi, ad esempio, ora abbiamo tre accorciatori di link in uso per scopi diversi in vari servizi. Queste sono le conseguenze.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Ora sarò il capitano dell'evidenza. Cosa bisogna fare? Prima di tutto, bisogna trasferire il servizio a un altro manager, a un altro team. Se il vostro team leader non si è ancora dimesso, allora in questo altro team, quando comprendete che il servizio assomiglia a un orfano, dovete includere qualcuno che abbia almeno una comprensione di esso.

La cosa principale: dovete avere procedure di trasferimento scritte in modo chiaro. Nel nostro caso, di solito seguo io questo aspetto, perché ho bisogno che tutto funzioni. Ai manager serve che venga consegnato rapidamente e quello che succederà dopo non è così importante per loro.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Il modo successivo per creare un orfano è: «Farlo in outsourcing, sarà più veloce, e poi lo passeremo al team». È chiaro che ognuno ha dei piani e delle priorità all'interno del team. Spesso il cliente aziendale pensa che un esternalizzatore farà le cose allo stesso modo del dipartimento tecnico presente in azienda. Anche se i loro motivi sono diversi. Nell'outsourcing si possono trovare soluzioni tecnologiche strane e algoritmi bizzarri.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Ad esempio, noi avevamo un servizio in cui Sphinx si trovava in posti inaspettati. Ti racconterò più avanti cosa abbiamo dovuto fare.

Gli esternalizzatori possono avere framework proprietari. Si tratta semplicemente di PHP nudo con del copia e incolla da un progetto precedente, dove si possono trovare di tutto. Grandi pasticci negli script di distribuzione, quando devi cambiare alcune righe in qualche file usando complicati script Bash, e questi script di distribuzione vengono richiamati da qualche terzo script. Alla fine cambi il sistema di distribuzione, scegli qualcosa di diverso, e puff, il tuo servizio smette di funzionare. Perché lì dovevi anche mettere altre 8 link tra diverse cartelle. Oppure, può capitare che mille registrazioni funzionano, ma centomila no.

Continuo a capitaneare. L'accettazione di un servizio esternalizzato è una procedura obbligatoria. A chi è capitato che un servizio esternalizzato arrivi, ma non venga accettato da nessuna parte? Non è così popolare come il servizio orfano, ma c'è comunque.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Il servizio deve essere controllato, deve essere valutato, devono essere cambiati le password. Noi abbiamo avuto un caso in cui ci hanno dato un servizio, e nell'admin era scritto «if login == ‘admin’ && password == ‘admin’…», direttamente nel codice. Stiamo qui a chiederci, e questo lo scrivono persone nel 2018?

Il test del volume di storage è anche una cosa necessaria. È importante vedere cosa succede con centomila registrazioni, anche prima di lanciare questo servizio in produzione.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Non dovrebbe essere imbarazzante inviare un servizio per la rifinitura. Quando dici: «Non accetteremo questo servizio, abbiamo 20 compiti, completateli e allora lo accetteremo», è normale. La coscienza non dovrebbe soffrire perché stai mettendo in difficoltà un manager o perché l'azienda spenderà dei soldi. L'azienda spenderà di più in seguito.

Noi abbiamo avuto un caso in cui abbiamo deciso di realizzare un progetto pilota in outsourcing.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

È stato consegnato in tempo, ed era l'unico criterio di qualità. Perciò è stato creato un altro progetto pilota, che in realtà non era più completamente pilota. Questi servizi sono stati accettati, tramite modalità amministrative è stato detto: ecco il vostro codice, ecco il team, ecco il vostro manager. I servizi hanno già iniziato a generare profitti. Tuttavia, di fatto, sono rimasti ancora orfani, nessuno capisce come funzionano e i manager si disconnettono in ogni modo dai loro compiti.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

C'è anche un ottimo concetto: lo sviluppo partigiano. Quando qualche dipartimento, di solito il dipartimento marketing, vuole testare un'ipotesi e ordina un servizio interamente in outsourcing. Inizia a ricevere traffico, chiudono i documenti, firmano i contratti con il fornitore, entra in esercizio e dicono: «Ragazzi, abbiamo un servizio qui, ha già del traffico, ci sta generando soldi, accettiamolo». Noi siamo tipo: «Aspetta, come è possibile».

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Un altro modo per ottenere un servizio orfano è quando un certo team si trova improvvisamente sopraffatto, e la direzione dice: «Passiamo il servizio di questo team a un altro team, che ha meno carico». E poi lo passeremo a un terzo team e cambiamo il manager. E alla fine, abbiamo di nuovo un orfano.

Qual è il problema con gli orfani?

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Per chi non lo sa, si tratta della nave da guerra Wasa, costruita in Svezia, famosa perché è affondata cinque minuti dopo il varo. E il re di Svezia, tra l'altro, non ha giustiziato nessuno per questo. È stata costruita da due generazioni di ingegneri che non sapevano costruire navi simili. Un effetto prevedibile.

La nave poteva affondare, tra l'altro, in maniera molto peggiore, ad esempio, quando a bordo ci sarebbe stato il re in mezzo a una tempesta. Invece, è affondata subito, secondo l'approccio agile questo è positivo — fallire presto.

Se falliamo presto, di solito non ci sono problemi. Ad esempio, durante l'accettazione viene rimandata per modifiche. Ma se falliamo già in produzione, quando sono stati investiti dei soldi, allora possono esserci problemi. Le conseguenze, come si dice nel business.

Quali sono i rischi dei servizi orfani:

  • Il servizio può rompersi improvvisamente.
  • Il servizio è difficile da riparare o non si ripara affatto.
  • Problemi di sicurezza.
  • Problemi con modifiche e aggiornamenti.
  • Se un servizio importante si rompe, la reputazione dell'azienda ne risente.

Cosa fare con i servizi orfani?

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Ripeto ancora una volta cosa fare. In primo luogo, deve esserci documentazione. I 7 anni in Banki.ru mi hanno insegnato che i tester non devono credere alle parole degli sviluppatori, e che l'operatività non deve fidarsi della parola di nessuno. Bisogna verificare.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

In secondo luogo, è necessario scrivere schemi di interazione, perché a volte i servizi che vengono accolti non molto bene contengono dipendenze di cui nessuno ha parlato. Ad esempio, gli sviluppatori hanno collegato un servizio al proprio API di Yandex.Maps o a Dadata. Il tuo limite gratuito è esaurito, tutto si è bloccato e non sai cosa sia successo. Tutti questi problemi devono essere descritti: nel servizio è usato Dadata, Sms, o altro.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

In terzo luogo, lavorare con il debito tecnico. Quando fai delle soluzioni temporanee o accetti un servizio e dici che qualcosa deve essere fatto, devi assicurarti che venga fatto. Perché poi potrebbe rivelarsi che un piccolo problema non è così piccolo e ci cadi dentro.

Con le questioni architetturali abbiamo avuto una storia proprio riguardo Sphinx. In uno dei servizi, Sphinx era utilizzato per inserire liste. Solo una lista con paginazione, ma veniva riindicizzata ogni notte. Era composto da due indici: un grande indicizzato ogni notte, e c'era anche un piccolo indice che vi era connesso. Ogni giorno, con il 50% di probabilità o saltava, o no, durante il rilascio l'indice si rompeva e le notizie smettevano di aggiornarsi sulla homepage. Inizialmente ci volevano 5 minuti, finché l'indice veniva riindicizzato, poi l'indice è cresciuto e a un certo punto ha iniziato a riindicizzarsi in 40 minuti. Quando l'abbiamo rimosso, abbiamo respirato di sollievo, perché era chiaro che sarebbe passato ancora un po' di tempo e il nostro indice sarebbe stato riindicizzato per un'intera giornata lavorativa. Questo sarebbe stato un fallimento per il nostro portale, otto ore senza notizie: finita, il business si è fermato.

Piano di lavoro con il servizio orfano

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

In realtà, è molto difficile fare ciò, perché il DevOps riguarda la comunicazione. Si desidera avere buoni rapporti con i propri colleghi, ma quando colpisci colleghi e manager con le normative, possono provare sentimenti contrastanti verso le persone che si comportano in questo modo.

Oltre a tutti questi punti, c'è un'altra cosa importante: per ciascun servizio specifico, per ciascun specifico segmento della procedura di deploy, devono rispondere persone specifiche. Quando non ci sono persone disponibili e si deve coinvolgere qualcun altro, studiare tutta la situazione diventa difficile.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Se tutto questo non ha funzionato e il servizio orfano è rimasto tale, nessuno vuole adottarlo, la documentazione non viene scritta, il team coinvolto in questo servizio si rifiuta di fare qualcosa, c'è un modo semplice: rifare tutto.

Cioè, riprendete i requisiti per il servizio da capo e scrivete un nuovo servizio, migliore, su una piattaforma migliore, senza soluzioni tecnologiche strane. E lo migrate in produzione.

Servizi orfani: il lato opposto dell'architettura a (micro)servizi

Abbiamo avuto una situazione in cui abbiamo preso un servizio su Yii 1 e abbiamo capito che non potevamo continuare a svilupparlo, perché ci erano finiti gli sviluppatori capaci di scrivere bene su Yii 1. Tutti gli sviluppatori scrivono bene su Symfony 3. Cosa fare? Abbiamo dedicato tempo, formato un team, assegnato un manager, riscritto il progetto e lentamente spostato su di esso il traffico.

Dopo di ciò, il vecchio servizio può essere eliminato. Questa è la mia procedura preferita, quando dal sistema di gestione delle configurazioni si deve rimuovere un servizio e poi assicurarsi che tutte le macchine in produzione siano state disattivate, in modo che non rimangano tracce per gli sviluppatori. Il repository in git rimane.

Questo è tutto ciò di cui volevo parlare, sono pronto a discuterne, è un tema controverso e molti ci hanno nuotato dentro.

Nelle slide si parlava del fatto che avete unificato i linguaggi. Come esempio veniva citato il ridimensionamento delle immagini. È davvero necessario essere rigorosi con un solo linguaggio? Perché il ridimensionamento di un'immagine in PHP, beh, si poteva tranquillamente fare anche in Golang.

In realtà, non è obbligatorio, come tutte le pratiche. In alcuni casi, potrebbe persino essere indesiderato. Ma bisogna comprendere che se nella vostra azienda ci sono 50 persone nel dipartimento tecnico, 45 di esse sono programmatori PHP, 3 sono devops che conoscono Python, Ansible, Puppet e simili, e solo uno di loro scrive un servizio in Go per il ridimensionamento delle immagini, quando se ne va, l'expertise se ne va con lui. E in questo caso dovrete cercare un sviluppatore di mercato specifico che conosca questo linguaggio, specialmente se è raro. Quindi, da un punto di vista organizzativo, è problematico. Dal punto di vista del devops, non dovrete solo clonare un set di playbook pronti che utilizzate per distribuire servizi, ma dovrete riscriverli da zero.

Attualmente stiamo sviluppando un servizio su Node.js, e questo sarà proprio uno spazio dedicato a ciascun sviluppatore con un linguaggio separato. Ma abbiamo pensato che ne valga la pena. Quindi, qui c'è da riflettere.

Come monitorate i vostri servizi? Come raccogliete e tracciate i log?

Raccogliamo i log in Elasticsearch e li mettiamo in Kibana, e a seconda che siano ambienti di produzione o di test, utilizziamo diversi raccoglitori. Da qualche parte utilizziamo Lumberjack, in altre parti non ricordo. Ci sono anche alcuni posti in determinati servizi dove installiamo Telegraf e inviamo i dati in altre destinazioni.

Come convivere con Puppet e Ansible in un'unica ambiente?

In realtà, attualmente abbiamo due ambienti, uno con Puppet e l'altro con Ansible. Stiamo lavorando per ibridarli. Ansible è un buon ambiente per le configurazioni iniziali, mentre Puppet è meno efficace per le impostazioni iniziali perché richiede intervento manuale diretto con l'ambiente, e Puppet garantisce la coerenza della configurazione. Questo significa che l'ambiente si mantiene automaticamente aggiornato, mentre per mantenere un macchina gestita da Ansible in stato attuale, è necessario eseguire regolarmente i playbook. Questa è la differenza.

Come mantenete la compatibilità? Avete configurazioni sia in Ansible che in Puppet?

Questo è il nostro grande dolore, sosteniamo la compatibilità manualmente e pensiamo a come passare a qualcos'altro. Risulta che Puppet gestisca i pacchetti e mantenga alcuni link, mentre Ansible, ad esempio, gestisce il codice e adatta le nuove configurazioni delle applicazioni.

Nella presentazione si parlava delle diverse versioni di Ruby. Qual è la soluzione?

Ci siamo trovati di fronte a questo problema in un certo luogo e dobbiamo tenerlo sempre a mente. Abbiamo semplicemente disattivato quella parte che funzionava con la versione di Ruby incompatibile con le applicazioni, tenendola separata.

Quest'anno la conferenza DevOpsDays Moscow si svolgerà il 7 dicembre a "Technopolis". Accettiamo proposte di relazioni fino all'11 novembre. Scriveteci se desiderate intervenire.

Le registrazioni per i partecipanti sono aperte, unitevi a noi!

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster