Història de l'arquitectura Dodo IS: el camí del back office

Habr està canviant el món. Fa més d'un any que fem blogs. Fa uns sis mesos, vam rebre un comentari completament lògic de Khabrovites: “Dodo, dius a tot arreu que tens el teu propi sistema. I quin és aquest sistema? I per què ho necessita una cadena de pizzes?

Ens vam asseure, vam pensar i ens vam adonar que tens raó. Intentem explicar-ho tot en els nostres dits, però surt a trossos trencats i enlloc hi ha una descripció completa del sistema. Així va començar un llarg viatge per recollir informació, buscar autors i escriure una sèrie d'articles sobre Dodo IS. Som-hi!

Agraïments: gràcies per compartir els vostres comentaris amb nosaltres. Gràcies a ell, finalment vam descriure el sistema, vam compilar un radar tècnic i aviat publicarem una gran descripció dels nostres processos. Sense vosaltres hauríem estat allà asseguts durant 5 anys més.

Història de l'arquitectura Dodo IS: el camí del back office

Sèrie d'articles "Què és Dodo IS?" parla de:

  1. Monòlit primerenc a Dodo IS (2011-2015). (En progrés...)
  2. El camí de back office: bases separades i bus. (estàs aquí)
  3. El camí lateral del client: façana sobre la base (2016-2017). (En progrés...)
  4. La història dels microserveis reals. (2018-2019). (En progrés...)
  5. Acabat de serrat del monòlit i estabilització de l'arquitectura. (En progrés…)

Si esteu interessats en saber alguna cosa més, escriviu als comentaris.

Opinió de l'autor sobre la descripció cronològica
Realitzo regularment una reunió per a nous empleats sobre el tema "Arquitectura del sistema". L'anomenem "Intro a Dodo IS Architecture" i forma part del procés d'incorporació dels nous desenvolupadors. Parlant d'una forma o altra de la nostra arquitectura, de les seves característiques, he nascut una certa aproximació històrica a la descripció.

Tradicionalment, considerem el sistema com un conjunt de components (tècnics o de nivell superior), mòduls empresarials que interactuen entre ells per aconseguir algun objectiu. I si aquesta visió està justificada per al disseny, no és del tot adequat per a la descripció i la comprensió. Hi ha diversos motius aquí:

  • La realitat és diferent de la que hi ha al paper. No tot surt com es pretenia. I ens interessa saber com va resultar i com funciona.
  • Presentació coherent de la informació. De fet, es pot anar cronològicament des del principi fins a l'estat actual.
  • De simple a complex. No universalment, però en el nostre cas sí. L'arquitectura va passar d'enfocaments més simples a altres més complexos. Sovint, a través de la complicació, es van resoldre problemes de velocitat i estabilitat d'implementació, així com desenes d'altres propietats de la llista de requisits no funcionals (aquí ben dit sobre el contrast de la complexitat amb altres requisits).

El 2011, l'arquitectura Dodo IS tenia aquest aspecte:

Història de l'arquitectura Dodo IS: el camí del back office

El 2020, s'ha tornat una mica més complicat i s'ha tornat així:

Història de l'arquitectura Dodo IS: el camí del back office

Com es va produir aquesta evolució? Per què es necessiten diferents parts del sistema? Quines decisions arquitectòniques es van prendre i per què? Descobrim-ho en aquesta sèrie d'articles.

Els primers problemes del 2016: per què els serveis haurien de sortir del monòlit

Els primers articles del cicle tractaran sobre els serveis que van ser els primers a separar-se del monòlit. Per posar-vos en context, us explicaré quins problemes teníem al sistema a principis del 2016, que vam haver de fer front a la separació de serveis.

Una única base de dades MySql, en la qual totes les aplicacions que existien en aquell moment a Dodo IS van escriure els seus registres. Les conseqüències van ser:

  • Càrrega pesada (amb el 85% de les sol·licituds representades per lectura).
  • La base ha crescut. A causa d'això, el seu cost i suport es va convertir en un problema.
  • Punt únic de fallada. Si una aplicació que escrivia a la base de dades de sobte començava a fer-ho de manera més activa, llavors altres aplicacions ho sentien per si mateixes.
  • Ineficiència en l'emmagatzematge i consultes. Sovint, les dades s'emmagatzemaven en una estructura que era convenient per a alguns escenaris però que no era adequada per a altres. Els índexs acceleren algunes operacions, però en poden frenar d'altres.
  • Alguns dels problemes es van eliminar mitjançant memòria cau i rèpliques de lectura a les bases de dades fetes precipitadament (aquest serà un article separat), però només els van permetre guanyar temps i no van resoldre fonamentalment el problema.

El problema era la presència del propi monòlit. Les conseqüències van ser:

  • Llançaments únics i rars.
  • Dificultat en el desenvolupament conjunt d'un gran nombre de persones.
  • Incapacitat per incorporar noves tecnologies, nous marcs i biblioteques.

Els problemes amb la base i el monòlit s'han descrit moltes vegades, per exemple, en el context d'accidents a principis de 2018 (Sigues com Munch, o unes poques paraules sobre el deute tècnic, El dia que Dodo IS es va aturar. Script asíncron и La història de l'ocell Dodo de la família del Fènix. La gran caiguda de Dodo IS), així que no m'atendré massa. Permeteu-me dir que volíem donar més flexibilitat a l'hora de desenvolupar serveis. En primer lloc, es tractava d'aquells que estaven més carregats i arrelats a tot el sistema: autenticació i seguiment.

El camí de back office: bases i bus separats

Navegació per capítols

  1. Esquema monòlit 2016
  2. Començant a descarregar el monòlit: separació d'autenticació i de seguiment
  3. Què fa l'Auth?
  4. D'on són les càrregues?
  5. Descàrrega d'auth
  6. Què fa el Tracker?
  7. D'on són les càrregues?
  8. Descàrrega de seguiment

Esquema monòlit 2016

Aquests són els blocs principals del monòlit Dodo IS 2016, i just a sota hi ha una transcripció de les seves tasques principals.
Història de l'arquitectura Dodo IS: el camí del back office
Lliurament al caixer. Comptabilitat de missatgers, emissió de comandes a missatgers.
Centre de contacte. Acceptació de comandes a través de l'operador.
Planta. Els nostres llocs web (dodopizza.ru, dodopizza.co.uk, dodopizza.by, etc.).
Aut. Servei d'autorització i autenticació per al back office.
Seguidor. Seguidor de comandes a la cuina. Servei de marcació d'estats de preparació a l'hora de preparar una comanda.
Caixer del Restaurant. Prendre comandes en un restaurant, interfícies de caixer.
Exporta. Càrrega d'informes en 1C per a la comptabilitat.
Notificacions i factures. Ordres de veu a la cuina (per exemple, "Ha arribat una nova pizza") + impressió de factures per als missatgers.
Gestor de torns. Interfícies per al treball del cap de torn: llista d'encàrrecs, gràfics de rendiment, trasllat d'empleats al torn.
Cap d'oficina. Interfícies per al treball del franquiciat i del gerent: recepció d'empleats, informes sobre el treball de la pizzeria.
Marcador del restaurant. Visualització de menús als televisors de les pizzeries.
admin. Configuració d'una pizzeria concreta: menú, preus, comptabilitat, codis promocionals, promocions, bàners web, etc.
Compte personal de l'empleat. Horaris de treball dels empleats, informació sobre els empleats.
Tauler de motivació de cuina. Una pantalla separada que penja a la cuina i mostra la velocitat de les pizzeres.
comunicació. Enviament de sms i correus electrònics.
Emmagatzematge de fitxers. Servei propi per rebre i emetre fitxers estàtics.

Els primers intents de resoldre els problemes ens van ajudar, però només van ser un respir temporal. No es van convertir en solucions de sistema, així que estava clar que s'havia de fer alguna cosa amb les bases. Per exemple, per dividir la base de dades general en diverses de més especialitzades.

Començant a descarregar el monòlit: separació d'autenticació i de seguiment

Els principals serveis que després van registrar i llegir de la base de dades més que altres:

  1. Auth. Servei d'autorització i autenticació per al back office.
  2. Seguidor. Seguidor de comandes a la cuina. Servei de marcació d'estats de preparació a l'hora de preparar una comanda.

Què fa l'Auth?

L'autenticació és un servei mitjançant el qual els usuaris inicien sessió al back office (hi ha una entrada independent independent al costat del client). També es demana a la sol·licitud que s'asseguri que els drets d'accés necessaris estan presents i que aquests drets no han canviat des de l'últim inici de sessió. A través d'ell, els dispositius entren a la pizzeria.

Per exemple, volem obrir una pantalla amb l'estat de les comandes acabades al televisor penjat al vestíbul. A continuació, obrim auth.dodopizza.ru, seleccionem "Iniciar sessió com a dispositiu", apareix un codi que es pot introduir en una pàgina especial a l'ordinador del cap de torn, indicant el tipus de dispositiu (dispositiu). El propi televisor canviarà a la interfície desitjada de la seva pizzeria i començarà a mostrar els noms dels clients les comandes dels quals hi estiguin preparades.

Història de l'arquitectura Dodo IS: el camí del back office

D'on són les càrregues?

Cada usuari connectat del back office va a la base de dades, a la taula d'usuaris per a cada sol·licitud, extreu l'usuari mitjançant una consulta sql i comprova si té l'accés i els drets necessaris a aquesta pàgina.

Cadascun dels dispositius fa el mateix només amb la taula de dispositius, comprovant el seu paper i el seu accés. Un gran nombre de peticions a la base de dades mestra comporta la seva càrrega i el malbaratament de recursos de la base de dades comuna per a aquestes operacions.

Descàrrega d'auth

Auth té un domini aïllat, és a dir, les dades sobre usuaris, inicis de sessió o dispositius entren al servei (de moment) i hi romanen. Si algú els necessita, anirà a aquest servei per obtenir dades.

ERA. L'esquema de treball inicialment era el següent:

Història de l'arquitectura Dodo IS: el camí del back office

M'agradaria explicar una mica com funcionava:

  1. Una sol·licitud des de l'exterior arriba al backend (hi ​​ha Asp.Net MVC), porta amb ella una galeta de sessió, que s'utilitza per obtenir dades de sessió de Redis(1). Conté informació sobre els accessos i, a continuació, l'accés al controlador està obert (3,4) o no.
  2. Si no hi ha accés, cal passar pel tràmit d'autorització. Aquí, per simplificar, es mostra com a part del camí en el mateix atribut, tot i que és una transició a la pàgina d'inici de sessió. En el cas d'un escenari positiu, obtindrem una sessió correctament completada i anirem al Controlador de Backoffice.
  3. Si hi ha dades, cal comprovar-ne la rellevància a la base de dades d'usuaris. Ha canviat el seu rol, no hauria de ser autoritzat a la pàgina ara? En aquest cas, després de rebre la sessió (1), cal anar directament a la base de dades i comprovar l'accés de l'usuari mitjançant la capa lògica d'autenticació (2). A continuació, a la pàgina d'inici de sessió o aneu al controlador. Un sistema tan senzill, però no del tot estàndard.
  4. Si es superen tots els procediments, saltem més a la lògica dels controladors i mètodes.

Les dades de l'usuari estan separades de totes les altres dades, s'emmagatzemen en una taula de pertinença separada, les funcions de la capa lògica AuthService poden convertir-se en mètodes API. Els límits del domini es defineixen amb força claredat: usuaris, els seus rols, dades d'accés, concessió i revocació d'accés. Tot sembla que es pugui treure en un servei a part.

CONVERTIR-SE EN. Així que van fer:

Història de l'arquitectura Dodo IS: el camí del back office

Aquest enfocament té una sèrie de problemes. Per exemple, cridar a un mètode dins d'un procés no és el mateix que cridar a un servei extern mitjançant http. La latència, la fiabilitat, el manteniment, la transparència de l'operació són completament diferents. Andrey Morevskiy va parlar amb més detall sobre aquests problemes en el seu informe. "50 ombres de microserveis".

El servei d'autenticació i, amb ell, el servei de dispositiu s'utilitzen per al back office, és a dir, per als serveis i interfícies utilitzats en producció. L'autenticació per als serveis de client (com ara un lloc web o una aplicació mòbil) es produeix per separat sense utilitzar Auth. La separació va durar aproximadament un any, i ara tornem a tractar aquest tema, transferint el sistema a nous serveis d'autenticació (amb protocols estàndard).

Per què va trigar tant la separació?
Hi va haver molts problemes al llarg del camí que ens van frenar:

  1. Volíem moure les dades d'usuari, dispositiu i d'autenticació de bases de dades específiques d'un país en una sola. Per fer-ho, vam haver de traduir totes les taules i l'ús de l'identificador int a l'identificador global UUId (reelaborat recentment aquest codi Roman Bukin "Uuid - una gran història d'una petita estructura" i projecte de codi obert Primitius). L'emmagatzematge de dades d'usuari (ja que és informació personal) té les seves limitacions i per a alguns països és necessari emmagatzemar-les per separat. Però l'identificador global de l'usuari ha de ser.
  2. Moltes taules de la base de dades tenen informació d'auditoria sobre l'usuari que ha realitzat l'operació. Això requeria un mecanisme addicional per a la coherència.
  3. Després de la creació dels serveis api, hi va haver un període llarg i gradual de transició a un altre sistema. El canvi havia de ser perfecte per als usuaris i requeria un treball manual.

Esquema de registre del dispositiu en una pizzeria:

Història de l'arquitectura Dodo IS: el camí del back office

Arquitectura general després de l'extracció del servei Auth and Devices:

Història de l'arquitectura Dodo IS: el camí del back office

Nota. Per al 2020, estem treballant en una nova versió d'Auth, que es basa en l'estàndard d'autorització OAuth 2.0. Aquest estàndard és força complex, però és útil per desenvolupar un servei d'autenticació de pas. A l'article "Subtileses de l'autorització: una visió general de la tecnologia OAuth 2.0» Nosaltres, Alexey Chernyaev, vam intentar explicar l'estàndard de la manera més senzilla i clara possible perquè estalvieu temps en estudiar-lo.

Què fa el Tracker?

Ara sobre el segon dels serveis carregats. El rastrejador realitza una doble funció:

  • D'una banda, la seva tasca és mostrar als empleats de la cuina quines comandes estan en marxa actualment, quins productes s'han de cuinar ara.
  • D'altra banda, digitalitzar tots els processos de la cuina.

Història de l'arquitectura Dodo IS: el camí del back office

Quan apareix un producte nou en una comanda (per exemple, pizza), es dirigeix ​​​​a l'estació de seguiment de desplegament. En aquesta estació, hi ha un fabricant de pizza que agafa un pa de la mida requerida i l'enrotlla, després de la qual cosa anota a la tauleta de seguiment que ha completat la seva tasca i transfereix la base de massa enrotllada a la següent estació: "Iniciació". .

Allà, el següent pizzer omple la pizza, després anota a la tauleta que ha completat la seva tasca i posa la pizza al forn (aquesta també és una estació separada que s'ha d'anotar a la tauleta). Aquest sistema va ser des del principi a Dodo i des del principi de l'existència de Dodo IS. Us permet fer un seguiment i digitalitzar completament totes les transaccions. A més, el rastrejador suggereix com cuinar un producte en concret, guia cada tipus de producte segons els seus esquemes de fabricació, emmagatzema el temps de cocció òptim del producte i fa un seguiment de totes les operacions del producte.

Història de l'arquitectura Dodo IS: el camí del back officeAixí es veu la pantalla de la tauleta a l'estació del rastrejador "Raskatka"

D'on són les càrregues?

Cadascuna de les pizzeries té unes cinc tauletes amb un rastrejador. El 2016 teníem més de 100 pizzeries (i ara més de 600). Cada una de les tauletes fa una sol·licitud al backend un cop cada 10 segons i treu dades de la taula de comandes (connexió amb el client i adreça), la composició de la comanda (connexió amb el producte i indicació de la quantitat), la taula de comptabilitat de motivació (el es fa un seguiment del temps de premsat). Quan un fabricant de pizza fa clic en un producte al rastrejador, les entrades de totes aquestes taules s'actualitzen. La taula de comandes és general, també conté insercions en acceptar una comanda, actualitzacions d'altres parts del sistema i nombroses lectures, per exemple, en un televisor que es penja en una pizzeria i mostra comandes acabades als clients.

Durant el període de lluita amb les càrregues, quan tot i tot s'emmagatzemava en memòria cau i es transferia a la rèplica asíncrona de la base, aquestes operacions amb el rastrejador van continuar anant a la base mestra. No hi hauria d'haver cap retard, les dades haurien d'estar actualitzades, la sincronització no és acceptable.

Així mateix, la manca de taules i índexs propis sobre ells no permetia escriure consultes més específiques adaptades al seu ús. Per exemple, pot ser eficaç per a un rastrejador tenir un índex per a una pizzeria en una taula de comandes. Sempre eliminem les comandes de pizzeria de la base de dades de seguiment. Al mateix temps, per rebre una comanda, no és tan important a quina pizzeria s'inclou, és més important quin client va fer aquesta comanda. I significa que l'índex del client és necessari. Tampoc és necessari que el rastrejador emmagatzemi l'identificador del rebut imprès o de les promocions de bonificació associades a la comanda a la taula de comandes. Aquesta informació no interessa el nostre servei de seguiment. En una base de dades monolítica comuna, les taules només podrien ser un compromís entre tots els usuaris. Aquest va ser un dels problemes originals.

ERA. L'arquitectura original era:

Història de l'arquitectura Dodo IS: el camí del back office

Fins i tot després de separar-se en processos separats, la major part de la base de codi es va mantenir comú per a diferents serveis. Tot el que hi havia a sota dels controladors era únic i vivia al mateix dipòsit. Hem utilitzat mètodes comuns de serveis, repositoris, una base comuna, en què es trobaven taules comunes.

Descàrrega de seguiment

El principal problema amb el rastrejador és que les dades s'han de sincronitzar entre diferents bases de dades. Aquesta també és la seva principal diferència amb la separació del servei d'autenticació, l'ordre i el seu estat poden canviar i s'han de mostrar en diferents serveis.

Acceptem una comanda a la Taxa del Restaurant (és un servei), s'emmagatzema a la base de dades en l'estat "Acceptat". Després d'això, hauria d'arribar al rastrejador, on canviarà el seu estat diverses vegades més: de "Cuina" a "Embalat". Al mateix temps, es poden produir algunes influències externes de la interfície del caixer o del Gestor de torns amb la comanda. Donaré els estats de la comanda amb la seva descripció a la taula:

Història de l'arquitectura Dodo IS: el camí del back office
L'esquema per canviar l'estat de les comandes és el següent:

Història de l'arquitectura Dodo IS: el camí del back office

Els estats canvien entre els diferents sistemes. I aquí el rastrejador no és un sistema definitiu en el qual es tanquen les dades. Hem vist diversos enfocaments possibles per a la partició en aquest cas:

  1. Concentrem totes les accions de comanda en un sol servei. En el nostre cas, aquesta opció requereix massa servei per treballar amb la comanda. Si ens aturem, obtindríem el segon monòlit. No resoldrem el problema.
  2. Un sistema fa una trucada a un altre. La segona opció ja és més interessant. Però amb ell, les cadenes de trucades són possibles (fallades en cascada), la connectivitat dels components és més alta, és més difícil de gestionar.
  3. Organitzem esdeveniments, i cada servei es comunica amb un altre a través d'aquests esdeveniments. Com a resultat, va ser la tercera opció que es va escollir, segons la qual tots els serveis comencen a intercanviar esdeveniments entre ells.

El fet d'haver escollit la tercera opció significava que el rastrejador tindria la seva pròpia base de dades, i per cada canvi en la comanda, enviava un esdeveniment al respecte, al qual s'hi subscriuen altres serveis i que també cau a la base de dades mestra. Per fer-ho, necessitem algun servei que garanteixi el lliurament de missatges entre serveis.

En aquell moment, ja teníem RabbitMQ a la pila, d'aquí la decisió final d'utilitzar-lo com a agent de missatges. El diagrama mostra la transició d'una comanda des del caixer del restaurant fins al tracker, on canvia el seu estat i la seva visualització a la interfície de comandes del gestor. CONVERTIR-SE EN:

Història de l'arquitectura Dodo IS: el camí del back office

Ruta de la comanda pas a pas
El camí de la comanda comença en un dels serveis d'origen de la comanda. Aquí teniu el caixer del restaurant:

  1. A la compra, la comanda està completament preparada i és hora d'enviar-la al rastrejador. Es llança l'esdeveniment al qual està subscrit el rastrejador.
  2. El rastrejador, acceptant una comanda per si mateix, la desa a la seva pròpia base de dades, fent l'esdeveniment "Comanda acceptada pel rastrejador" i enviant-la a RMQ.
  3. Ja hi ha diversos gestors subscrits al bus d'esdeveniments per comanda. Per a nosaltres és important el que fa la sincronització amb una base monolítica.
  4. El gestor rep un esdeveniment, en selecciona les dades que són significatives per a ell: en el nostre cas, aquest és l'estat de la comanda "Acceptada pel rastrejador" i actualitza la seva entitat de comanda a la base de dades principal.

Si algú necessita una comanda de les comandes de la taula monolítica, també la podeu llegir des d'allà. Per exemple, la interfície de comandes del Gestor de torns necessita això:

Història de l'arquitectura Dodo IS: el camí del back office

Tots els altres serveis també es poden subscriure per demanar esdeveniments al rastrejador per utilitzar-los per si mateixos.

Si al cap d'un temps la comanda es posa en funcionament, el seu estat canvia primer a la seva base de dades (base de dades Tracker) i immediatament es genera l'esdeveniment "OrderIn Progress". També entra a RMQ, des d'on es sincronitza en una base de dades monolítica i es lliura a altres serveis. Pot haver-hi diversos problemes al llarg del camí, es poden trobar més detalls a l'informe de Zhenya Peshkov sobre els detalls d'implementació d'Eventual Consistency al Tracker.

Arquitectura final després de canvis en l'autenticació i el seguiment

Història de l'arquitectura Dodo IS: el camí del back office

Resumint el resultat intermedi: Inicialment, vaig tenir la idea d'empaquetar la història de nou anys del sistema Dodo IS en un sol article. Volia parlar de manera ràpida i senzilla de les etapes de l'evolució. No obstant això, assegut al material, em vaig adonar que tot és molt més complicat i interessant del que sembla.

Reflexionant sobre els beneficis (o la manca d'aquests) d'aquest material, vaig arribar a la conclusió que el desenvolupament continu és impossible sense anals complets d'esdeveniments, retrospectives detallades i anàlisi de les meves decisions passades.

Espero que us hagi estat útil i interessant conèixer el nostre camí. Ara estic davant d'una tria quina part del sistema Dodo IS descriure al següent article: escriure als comentaris o votar.

Només els usuaris registrats poden participar en l'enquesta. Inicia sessiósi us plau.

Quina part de Dodo IS t'agradaria saber al següent article?

  • 24,1%Monòlit primerenc a Dodo IS (2011-2015)14

  • 24,1%Primers problemes i les seves solucions (2015-2016)14

  • 20,7%El camí costat client: façana sobre base (2016-2017)12

  • 36,2%La història dels veritables microserveis (2018-2019)21

  • 44,8%Acabat de serrat del monòlit i estabilització de l'arquitectura26

  • 29,3%Sobre els plans addicionals per al desenvolupament del sistema17

  • 19,0%No vull saber res sobre Dodo IS11

Han votat 58 usuaris. 6 usuaris es van abstenir.

Font: www.habr.com

Afegeix comentari