Cosa sapemu di i microservizi

Bonghjornu! Mi chjamu Vadim Madison, guidu u sviluppu di a piattaforma Avito System. Hè statu dettu più di una volta cumu noi in a cumpagnia si move da una architettura monolitica à una microservizi. Hè u tempu di sparte cumu avemu trasfurmatu a nostra infrastruttura per ottene u massimu di i microservizi è impediscenu di perdemu in elli. Cumu PaaS ci aiuta quì, cumu avemu simplificatu l'implementazione è ridutta a creazione di un microserviziu à un clic - leghje. Micca tuttu ciò chì scrivu quì sottu hè cumplettamente implementatu in Avito, un pocu di questu hè cumu sviluppemu a nostra piattaforma.

(È à a fine di questu articulu, parleraghju di l'uppurtunità di assistisce à un seminariu di trè ghjorni da l'espertu di l'architettura di microservizi Chris Richardson).

Cosa sapemu di i microservizi

Cumu avemu ghjuntu à i microservizi

Avito hè unu di i più grandi siti classificati in u mondu; più di 15 milioni di publicità novi sò publicati annantu à ghjornu. U nostru backend accetta più di 20 mila richieste per seconda. Attualmente avemu parechje centinaie di microservizi.

Avemu custruitu una architettura di microserviziu dapoi parechji anni. Cumu esattamente - i nostri culleghi in dettagliu hà dettu à a nostra sezione in RIT++ 2017. À CodeFest 2017 (vede. видео), Sergey Orlov è Mikhail Prokopchuk spiegà in dettagliu perchè avemu bisognu di a transizione à i microservizi è quale rolu Kubernetes hà ghjucatu quì. Ebbè, avà facemu tuttu per minimizzà i costi di scaling chì sò inerenti in una tale architettura.

Inizialmente, ùn avemu micca creatu un ecosistema chì ci aiutava in modu cumpletu à sviluppà è lancià microservizi. Simply raccolte suluzioni open source sensibili, lanciate in casa è invitanu u sviluppatore à trattà cun elli. In u risultatu, si n'andò in una decina di lochi (dashboards, servizii internu), dopu à quale ellu hè diventatu più forte in u so desideriu di cutà u codice in u vechju modu, in un monolitu. U culore verde in i diagrammi sottu indica ciò chì u sviluppatore faci una manera o l'altru cù e so mani, è u culore giallu indica l'automatizazione.

Cosa sapemu di i microservizi

Avà in l'utilità PaaS CLI, un novu serviziu hè creatu cù un cumandamentu, è una nova basa di dati hè aghjuntu cù dui più è implementatu à Stage.

Cosa sapemu di i microservizi

Cumu superà l'era di a "frammentazione di i microservizi"

Cù una architettura monolitica, per a cunsistenza di i cambiamenti in u pruduttu, i sviluppatori sò stati custretti à capisce ciò chì passava cù i so vicini. Quandu u travagliu nantu à a nova architettura, i cuntesti di serviziu ùn dependenu più di l'altri.

Inoltre, per una architettura di microserviziu per esse efficace, parechji prucessi anu da esse stabilitu, vale à dì:

• logging;
• dumanda traccia (Jaeger);
• aggregazione di errore (Sentry);
• status, missaghji, evenimenti da Kubernetes (Event Stream Processing);
• limite di razza / circuit breaker (pudete aduprà Hystrix);
• cuntrollu di a cunnessione di u serviziu (usemu Netramesh);
• surviglianza (Grafana);
• assemblea (TeamCity);
• cumunicazione è notificazione (Slack, email);
• seguimentu di u travagliu; (Jira)
• preparazione di ducumenti.

Per assicurà chì u sistema ùn perde micca a so integrità è ferma efficace mentre scala, avemu ripensatu l'urganizazione di i microservizi in Avito.

Cumu gestionemu i microservizi

I seguenti aiutanu à implementà una "pulitica di partitu" unificata trà parechji microservizi Avito:

  • dividendu l'infrastruttura in strati;
  • Piattaforma cum'è serviziu (PaaS) cuncettu;
  • monitorizà tuttu ciò chì succede cù i microservizi.

I strati di astrazione di l'infrastruttura includenu trè strati. Andemu da cima à fondu.

A. Top - rete di serviziu. Prima avemu pruvatu à Istio, ma hè risultatu chì usa troppu risorse, chì hè troppu caru per i nostri volumi. Dunque, l'ingegnere senior in a squadra di l'architettura Alexander Lukyanchenko hà sviluppatu a so propria suluzione - Netramesh (dispunibule in Open Source), chì avemu aduprà oghje in a pruduzzione è chì cunsuma parechje volte menu risorse chè Istio (ma ùn face micca tuttu ciò chì Istio pò vantà).
B. Medium - Kubernetes. Implementemu è operemu microservizi nantu à questu.
C. Bottom - bare metal. Ùn usemu micca nuvole o cose cum'è OpenStack, ma si basanu interamente in metallo nudu.

Tutti i strati sò cumminati da PaaS. È sta piattaforma, à u turnu, hè custituita da trè parti.

I. Generatori, cuntrullata via una utilità CLI. Hè ella chì aiuta u sviluppatore à creà un microserviziu in u modu ghjustu è cun un minimu sforzu.

II. Cullettore cunsolidatu cù u cuntrollu di tutti i strumenti attraversu un dashboard cumuni.

III. Storage. Cunnette cù pianificatori chì stabiliscenu automaticamente i triggers per azzione significativa. Grazie à un tali sistema, ùn manca micca un compitu solu perchè qualchissia s'hè scurdatu di stallà un compitu in Jira. Utilizemu un strumentu internu chjamatu Atlas per questu.

Cosa sapemu di i microservizi

L'implementazione di i microservizi in Avito hè ancu realizatu secondu un schema unicu, chì simplificà u cuntrollu di elli in ogni stadiu di sviluppu è liberazione.

Cumu funziona un pipeline di sviluppu di microserviziu standard?

In generale, a catena di creazione di microservizi pare cusì:

CLI-push → Integrazione Continua → Bake → Deploy → Test artificiali → Test Canary → Squeeze Testing → Produzione → Mantenimentu.

Andemu à traversu esattamente in questu ordine.

CLI-push

• Crià un microserviziu.
Avemu luttatu per un bellu pezzu per insignà à ogni sviluppatore cumu fà i microservizi. Questu includia scrive struzzioni dettagliate in Confluence. Ma i schemi anu cambiatu è sò stati supplementati. U risultatu hè chì un collu di buttiglia apparsu à u principiu di u viaghju: hà pigliatu assai più tempu per lancià i microservizi, è sempre i prublemi sò spessu suscitati durante a so creazione.

In fine, avemu custruitu una utilità CLI simplice chì automatizza i passi basi quandu crea un microserviziu. In fatti, rimpiazza u primu git push. Eccu esattamente ciò chì face.

- Crea un serviziu secondu un mudellu - passu à passu, in modu "mago". Avemu mudelli per i principali linguaggi di prugrammazione in u backend Avito: PHP, Golang è Python.

- Un cumandamentu à u tempu implementa un ambiente per u sviluppu lucale nantu à una macchina specifica - Minikube hè lanciatu, i grafici Helm sò generati automaticamente è lanciati in kubernetes lucali.

- Cunnette a basa di dati necessaria. U sviluppatore ùn hà micca bisognu di cunnosce l'IP, login è password per accede à a basa di dati chì hà bisognu - sia lucale, in Stage, o in produzzione. Inoltre, a basa di dati hè implementata immediatamente in una cunfigurazione tolerante à i difetti è cù equilibriu.

- Esegue l'assemblea in diretta stessu. Diciamu chì un sviluppatore hà correttu qualcosa in un microserviziu attraversu u so IDE. L'utilità vede cambiamenti in u sistema di fugliale è, basatu annantu à elli, ricustruisce l'applicazione (per Golang) è riavvia. Per PHP, simpricimenti trasmettemu u repertoriu in u cubu è quì u live-reload hè ottenutu "automaticamente".

- Genera autotest. In forma di spazii, ma abbastanza adattatu per l'usu.

• Impiegazione di Microservice.

Implementà un microserviziu era un pocu di travagliu per noi. I seguenti eranu necessarii:

I. Dockerfile.

II. Config.
III. Graficu Helm, chì ellu stessu hè ingombrante è include:

- i grafici stessi;
- mudelli;
- valori specifichi tenendu in contu i diversi ambienti.

Avemu cacciatu u dulore di a riformulazione di i manifesti Kubernetes in modu chì sò avà generati automaticamente. Ma u più impurtante, anu simplificatu l'implementazione à u limitu. Da avà avemu un Dockerfile, è u sviluppatore scrive tutta a cunfigurazione in un solu file app.toml.

Cosa sapemu di i microservizi

Iè, è in app.toml stessu ùn ci hè nunda di fà per un minutu. Specificemu induve è quante copie di u serviziu per suscitarà (nantu à u servitore dev, in staging, in a produzzione), è indicà e so dependenze. Avvisu a dimensione di a linea = "small" in u bloccu [motore]. Questu hè u limitu chì serà attribuitu à u serviziu via Kubernetes.

Allora, basatu annantu à a cunfigurazione, tutti i charts Helm necessarii sò generati automaticamente è e cunnessione à e basa di dati sò creati.

• Validazione basica. Tali cuntrolli sò ancu automatizati.
Hè bisognu di seguità:
- ci hè un Dockerfile;
- ci hè app.toml;
- Ci hè una documentazione dispunibule?
- a dependenza hè in ordine?
- se e regule d'alerta sò state stabilite.
À l'ultimu puntu: u pruprietariu di u serviziu stessu determina quale metrica di u produttu per monitorà.

• Preparazione di ducumentazione.
Sempre una zona problematica. Sembra esse u più ovvi, ma à u stessu tempu hè ancu un record "spessu scurdatu", è dunque un ligame vulnerabile in a catena.
Hè necessariu chì ci sia documentazione per ogni microserviziu. Include i seguenti blocchi.

I. Breve descrizzione di u serviziu. Litteralmente uni pochi di frasi nantu à ciò chì face è perchè hè necessariu.

II. Link di schema di l'architettura. Hè impurtante chì, cun un sguardu rapidu, hè faciule da capisce, per esempiu, s'ellu si usa Redis per caching o cum'è u principale magazzinu di dati in modu persistente. In Avito per avà questu hè un ligame à Confluence.

III. Runbook. Una breve guida nantu à l'iniziu di u serviziu è l'intricacies di a gestione.

IV. FAQ, induve saria bonu per anticipà i prublemi chì i vostri culleghi puderanu scontru quandu u travagliu cù u serviziu.

V. Descrizzione di endpoints per l'API. Se di colpu ùn avete micca specificatu e destinazioni, i culleghi chì i so microservizi sò ligati à u vostru, guasi sicuru, pagheranu per questu. Avà usemu Swagger è a nostra suluzione chjamata brevi per questu.

VI. Etichette. O marcatori chì mostranu à quale pruduttu, funziunalità o divisione strutturale di a cumpagnia appartene u serviziu. Vi aiutanu à capisce rapidamente, per esempiu, s'ellu vi tagliate e funziunalità chì i vostri culleghi anu sviluppatu per a stessa unità di cummerciale una settimana fà.

VII. Pruprietari o pruprietarii di u serviziu. In a maiò parte di i casi, - o elli - ponu esse determinati automaticamente cù PaaS, ma per esse in u latu sicuru, avemu bisognu chì u sviluppatore li specifichi manualmente.

Infine, hè una bona pratica per rivisione a documentazione, simile à a rivista di codice.

Integrazione cuntinua

  • Preparazione di repository.
  • Creazione di una pipeline in TeamCity.
  • Stabbilimentu di diritti.
  • Ricerca i pruprietarii di serviziu. Ci hè un schema hibridu quì - marcatura manuale è automatizazione minima da PaaS. Un schema cumplettamente autumàticu falla quandu i servizii sò trasferiti per supportu à un altru squadra di sviluppu o, per esempiu, se u sviluppatore di u serviziu abbanduneghja.
  • Registrazione di un serviziu in Atlas (vede sopra). Cù tutti i so patroni è dipendenze.
  • Verificate e migrazioni. Cuntrollamu s'ellu ci hè un potenziale periculoso. Per esempiu, in unu d'elli un alter table o qualcosa d'altru pop up chì pò rompe a cumpatibilità di u schema di dati trà e diverse versioni di u serviziu. Allora a migrazione ùn hè micca realizata, ma posta in un abbunamentu - u PaaS deve signalà u pruprietariu di u serviziu quandu hè sicuru d'utilizà.

Cuoce

A prossima tappa hè i servizii di imballaggio prima di implementazione.

  • Custruisce l'applicazione. Sicondu i classici - in una maghjina Docker.
  • Generazione di charts Helm per u serviziu stessu è risorse cunnesse. Inclusu per basa di dati è cache. Sò creati automaticamente in cunfurmità cù a cunfigurazione app.toml chì hè stata generata in u stadiu CLI-push.
  • Creazione di biglietti per l'amministratori per apre i porti (quandu necessariu).
  • Esecuzione di teste di unità è calculà a copertura di codice. Se a cobertura di u codice hè sottu à u limitu specificatu, u più prubabile di u serviziu ùn andarà più - à implementazione. S'ellu hè nantu à l'acceptable, u serviziu serà attribuitu un coefficient "pessimizing": allora, se ùn ci hè micca una migliione di l'indicatore cù u tempu, u sviluppatore riceve una notificazione chì ùn ci hè micca prugressu in termini di teste ( è ci vole à fà qualcosa).
  • Cuntabilità per limitazioni di memoria è CPU. Scrivemu principalmente microservizi in Golang è eseguimu in Kubernetes. Da quì una sutilezza assuciata à a peculiarità di a lingua Golang: per automaticamente, quandu si cumincianu, tutti i nuclei nantu à a macchina sò usati, se ùn avete micca stabilitu esplicitamente a variàbile GOMAXPROCS, è quandu parechji tali servizii sò lanciati nantu à a stessa macchina, cumincianu. per cumpete per i risorse, interferendu l'un l'altru. I grafici quì sottu mostranu cumu cambia u tempu d'esekzione se eseguite l'applicazione senza cuntenzione è in a corsa per u modu di risorse. (E fonti di grafici sò ccà).

Cosa sapemu di i microservizi

U tempu di esecuzione, menu hè megliu. Massimu: 643 ms, minimu: 42 ms. A foto hè clicable.

Cosa sapemu di i microservizi

U tempu per a cirurgia, menu hè megliu. Massimu: 14091 ns, minimu: 151 ns. A foto hè clicable.

À a fase di preparazione di l'assemblea, pudete stabilisce sta variàbile in modu esplicitu o pudete aduprà a biblioteca automaxprocs da i ragazzi di Uber.

Impulsà

• Cunvenzioni di cuntrollu. Prima di cumincià à furnisce assemblee di serviziu à i vostri ambienti previsti, avete bisognu di verificà e seguenti:
- Endpoints API.
- Conformità di e risposti di i punti finali API cù u schema.
- Formatu di log.
- Impostazione di intestazioni per e dumande à u serviziu (attualmente questu hè fattu da netramesh)
- Stabbilimentu di u token di u pruprietariu quandu mandate missaghji à l'autobus di l'avvenimentu. Questu hè necessariu per seguità a cunnessione di i servizii à traversu l'autobus. Pudete mandà sia dati idempotenti à l'autobus, chì ùn aumenta micca a cunnessione di i servizii (chì hè bonu), è e dati di l'affari chì rinforza a cunnessione di i servizii (chì hè assai male!). È à u puntu chì sta cunnessione diventa un prublema, capisce quale scrive è leghje l'autobus aiuta à separà bè i servizii.

Ùn ci sò micca assai cunvenzioni in Avito ancu, ma a so piscina hè in espansione. Più tali accordi sò dispunibuli in una forma chì a squadra pò capisce è capisce, più faciule hè di mantene a coherenza trà i microservizi.

Testi sintetici

• Prova di ciclu chjusu. Per questu avemu avà aduprà open source Hoverfly.io. Prima, registra a carica reale nantu à u serviziu, dopu - solu in un ciclu chjusu - l'emulate.

• Stress Testing. Pruvemu di purtà tutti i servizii à un rendiment ottimali. È tutte e versioni di ogni serviziu deve esse sottumessu à a prova di carica - in questu modu pudemu capisce a prestazione attuale di u serviziu è a diffarenza cù e versioni precedenti di u stessu serviziu. Se, dopu un aghjurnamentu di serviziu, u so rendimentu hè cascatu da una volta è mezu, questu hè un signalu chjaru per i so patroni: avete bisognu di scavà in u codice è curreghja a situazione.
Utilizemu e dati raccolti, per esempiu, per implementà currettamente l'autoscaling è, in fine, capiscenu in generale quantu scalabile hè u serviziu.

Durante a prova di carica, verificamu se u cunsumu di risorse rispetta i limiti stabiliti. È ci focalizemu principalmente in l'estremi.

a) Fighjemu a carica tutale.
- Troppu chjuca - assai prubabilmente qualcosa ùn funziona micca in tuttu se a carica scende di colpu parechje volte.
- Troppu grande - ottimisazione necessaria.

b) Fighjemu u cutoff secondu RPS.
Quì avemu vistu a diffarenza trà a versione attuale è a precedente è a quantità tutale. Per esempiu, se un serviziu pruduce 100 rps, allora hè o pocu scrittu, o questu hè a so specificità, ma in ogni casu, questu hè un mutivu per vede u serviziu assai vicinu.
Se, à u cuntrariu, ci sò troppu RPS, allora forse ci hè un tipu di bug è alcuni di l'endpoint anu cessatu di eseguisce u payload, ma un altru hè simplicemente attivatu. return true;

Test canari

Dopu avè passatu i testi sintetici, testemu u microserviziu nantu à un picculu numeru di utilizatori. Cuminciamu cun cura, cù una piccula parte di u publicu destinatu à u serviziu - menu di 0,1%. In questa fase, hè assai impurtante chì i metrici tecnichi è di produttu curretti sò inclusi in u monitoraghju in modu chì mostranu u prublema in u serviziu u più prestu pussibule. U tempu minimu per una prova canaria hè 5 minuti, u principale hè 2 ore. Per i servizii cumplessi, avemu stabilitu l'ora manualmente.
Analizemu:
- metriche specifichi di lingua, in particulare, travagliadori php-fpm;
- errore in Sentry;
- stati di risposta;
- tempu di risposta, esatta è mediu;
- latenza;
- eccezzioni, trattatu è unhandled;
- metrica di u produttu.

Squeeze Testing

Squeeze Testing hè ancu chjamatu teste "squeezing". U nomu di a tecnica hè statu introduttu in Netflix. A so essenza hè chì prima riempia una istanza cù u trafficu veru finu à u puntu di fallimentu è cusì stabilisce u so limitu. Allora aghjunghjemu un altru esempiu è caricate stu paru - novu à u massimu; vedemu u so tettu è u delta cù u primu "squeeze". È cusì cunnettamu una istanza à una volta è calculemu u mudellu di cambiamenti.
I dati di prova attraversu "spremere" scorri ancu in una basa di dati di metrica cumuni, induve o arricchiscemu i risultati di carica artificiale cun elli, o ancu rimpiazzà "sintetici" cun elli.

Pruduzzione

• Scaling. Quandu stendemu un serviziu à a produzzione, monitoremu cumu si scala. In a nostra sperienza, u monitoraghju solu l'indicatori di CPU hè inefficace. Scaling auto cù benchmarking RPS in a so forma pura funziona, ma solu per certi servizii, cum'è streaming online. Allora guardemu prima à e metriche di produttu specifichi di l'applicazione.

In u risultatu, quandu si scala, analizemu:
- Indicatori CPU è RAM,
- u numeru di dumande in a fila,
- tempu di risposta,
- previsione basata nantu à dati storichi accumulati.

Quandu scaling un serviziu, hè ancu impurtante di monitorà e so dependenze in modu chì ùn scalemu micca u primu serviziu in a catena, è quelli chì accede à falla sottu a carica. Per stabilisce una carica accettabile per tuttu u gruppu di servizii, fighjemu i dati storichi di u serviziu dipendente "più vicinu" (basatu nantu à una cumminazione di indicatori CPU è RAM, accumpagnati da metriche specifiche per l'app) è paragunate cù i dati storichi. di u serviziu di inizializazione, è cusì in tutta a "catena di dipendenza" ", da cima à fondu.

Serviziu

Dopu chì u microserviziu hè messu in opera, pudemu attaccà triggers.

Eccu situazioni tipiche in quale si verificanu i triggers.
- Migrazioni potenzialmente periculose rilevate.
- L'aghjurnamenti di sicurezza sò stati liberati.
- U serviziu stessu ùn hè micca aghjurnatu per un bellu pezzu.
- A carica nantu à u serviziu hè notevolmente diminuita o alcune di e so metriche di u produttu sò fora di a gamma normale.
- U serviziu ùn risponde più à i requisiti di a nova piattaforma.

Certi di i triggers sò rispunsevuli di a stabilità di u funziunamentu, alcuni - cum'è una funzione di mantenimentu di u sistema - per esempiu, qualchì serviziu ùn hè statu implementatu per un bellu pezzu è a so maghjina di basa hà cessatu di passà i cuntrolli di sicurezza.

Dashboard

In corta, u dashboard hè u pannellu di cuntrollu di tuttu u nostru PaaS.

  • Un unicu puntu di infurmazione nantu à u serviziu, cù dati nantu à a so copertura di teste, u numeru di e so imagine, u numeru di copie di pruduzzione, versioni, etc.
  • Un strumentu per filtrà e dati per servizii è etichette (marcatori di appartenenza à unità di cummerciale, funziunalità di u produttu, etc.)
  • Un strumentu per l'integrazione cù l'arnesi di l'infrastruttura per a traccia, u logu è u monitoraghju.
  • Un unicu puntu di documentazione di serviziu.
  • Un puntu di vista unicu di tutti l'avvenimenti attraversu i servizii.

Cosa sapemu di i microservizi
Cosa sapemu di i microservizi
Cosa sapemu di i microservizi
Cosa sapemu di i microservizi

Tuttu

Prima di l'introduzione di PaaS, un novu sviluppatore puderia passà parechje settimane per capiscenu tutti l'arnesi necessarii per lancià un microserviziu in produzzione: Kubernetes, Helm, e nostre funzioni internu di TeamCity, stabilisce cunnessione à basa di dati è cache in una manera tolerante à i difetti, ecc. piglia un paru d'ore per leghje u quickstart è creà u serviziu stessu.

Aghju datu un rapportu nantu à questu tema per HighLoad++ 2018, pudete vede видео и prisentazione.

Bonus track per quelli chì leghjenu finu à a fine

Avemu in Avito urganizemu una furmazione interna di trè ghjorni per i sviluppatori da Chris Richardson, un espertu in l'architettura di microservizi. Vulemu dà a pussibilità di participà à questu à unu di i lettori di stu post. U prugramma di furmazione hè statu publicatu.

A furmazione serà da 5 à 7 d'aostu in Mosca. Quessi sò ghjorni di travagliu chì seranu occupati cumplettamente. U pranzu è a furmazione seranu in u nostru uffiziu, è u participante sceltu pagherà u viaghju è l'alloghju stessu.

Pudete dumandà a participazione in questa forma di Google. Da voi - a risposta à a quistione perchè avete bisognu di assistisce à a furmazione è infurmazione nantu à cumu cuntattate. Rispondi in inglese, perchè Chris sceglierà u participante chì assisterà ellu stessu à a furmazione.
Avemu da annunzià u nome di u participant à a furmazione in un aghjurnamentu di questu post è nantu à e rete suciale Avito per i sviluppatori (AvitoTech in Facebook, Vkontakte, Twitter) più tardi di u 19 di lugliu.

Source: www.habr.com

Add a comment