{"id":31124,"date":"2019-10-31T21:39:36","date_gmt":"2019-10-31T18:39:36","guid":{"rendered":"https:\/\/prohoster.info\/blog\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie\/"},"modified":"2019-10-31T21:39:36","modified_gmt":"2019-10-31T18:39:36","slug":"stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","status":"publish","type":"post","link":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","title":{"rendered":"Blocurile de baz\u0103 ale aplica\u021biilor distribuite. A doua aproximare","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Anun\u021b<\/strong><\/p>\n<p><\/p>\n<p><em>Colegi, \u00een mijlocul verii, planific s\u0103 public un nou ciclu de articole despre proiectarea sistemelor de servicii de mas\u0103: \u201eExperimentul VTrade\u201d \u2014 o \u00eencercare de a scrie un cadru pentru sistemele de tranzac\u021bionare. \u00cen acest ciclu, vom analiza teoria \u0219i practica construirii unei burse, a unei licita\u021bii \u0219i a unui magazin. La finalul articolului, propun s\u0103 vot\u0103m pentru cele mai interesante subiecte pentru voi.<br \/>\n<\/em><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Blocurile de baz\u0103 ale aplica\u021biilor distribuite. A doua aproximare\" src=\"\/wp-content\/uploads\/2019\/04\/358996733e805327b587176f4f992aea.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Acesta este articolul de \u00eencheiere al ciclului despre aplica\u021biile reactive distribuite folosind Erlang\/Elixir. \u00cen <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446028\/\">articolul nostru ini\u021bial<\/a><\/noindex> pute\u021bi g\u0103si fundamentele teoretice ale arhitecturii reactive. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446108\/\">Al doilea articol<\/a><\/noindex> ilustreaz\u0103 principalele modele \u0219i mecanisme de construire a acestor sisteme.<\/p>\n<p><\/p>\n<p>Ast\u0103zi vom discuta despre dezvoltarea bazei de cod \u0219i a proiectelor \u00een general. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"organizaciya-servisov\">Organizarea serviciilor<\/h2>\n<p><\/p>\n<p>\u00cen via\u021ba real\u0103, c\u00e2nd dezvolt\u0103m un serviciu, adesea trebuie s\u0103 combin\u0103m mai multe modele de interac\u021biune \u00eentr-un singur controler. De exemplu, serviciul de utilizatori, care se ocup\u0103 de gestionarea profilurilor utilizatorilor proiectului, trebuie s\u0103 r\u0103spund\u0103 la cererile req-resp \u0219i s\u0103 anun\u021be actualiz\u0103rile profilurilor prin pub-sub. Acest caz este destul de simplu: pentru messaging exist\u0103 un singur controler care implementa logica serviciului \u0219i public\u0103 actualiz\u0103rile.<\/p>\n<p><\/p>\n<p>Situa\u021bia devine mai complex\u0103 atunci c\u00e2nd trebuie s\u0103 implement\u0103m un serviciu distribuit rezistent la erori. S\u0103 ne imagin\u0103m c\u0103 cerin\u021bele pentru utilizatori s-au schimbat: <\/p>\n<p><\/p>\n<ol>\n<li>acum serviciul trebuie s\u0103 proceseze cereri pe 5 noduri din cluster, <\/li>\n<li>s\u0103 aib\u0103 capacitatea de a executa sarcini de fundal pentru procesare, <\/li>\n<li>\u0219i de asemenea s\u0103 fie capabil s\u0103 gestioneze dinamic listele de abonamente pentru actualiz\u0103rile profilurilor.<\/li>\n<\/ol>\n<p><\/p>\n<p><em>Observa\u021bie:<\/em> Problema stoc\u0103rii consistente \u0219i replic\u0103rii datelor nu o discut\u0103m. S\u0103 presupunem c\u0103 aceste probleme au fost solu\u021bionate anterior \u0219i c\u0103 \u00een sistem exist\u0103 deja un strat de stocare fiabil \u0219i scalabil, iar handlerii au mecanisme de interac\u021biune cu acesta.<\/p>\n<p><\/p>\n<p>Descrierea formal\u0103 a serviciului utilizatori s-a complicat. Din perspectiva programatorului, datorit\u0103 utiliz\u0103rii messaging-ului, modific\u0103rile sunt minime. Pentru a satisface prima cerin\u021b\u0103, trebuie s\u0103 configur\u0103m balansarea la punctul de schimb req-resp. <\/p>\n<p><\/p>\n<p>Cererea de procesare a sarcinilor de fundal apare frecvent. \u00cen users, acestea pot fi verific\u0103ri ale documentelor utilizatorilor, procesarea multimedia \u00eenc\u0103rcate sau sincronizarea datelor cu re\u021belele sociale. Aceste sarcini trebuie cumva distribuite \u00een cadrul cluster-ului \u0219i controlate \u00een ceea ce prive\u0219te progresul. Prin urmare, avem dou\u0103 op\u021biuni de solu\u021bionare: fie utiliz\u0103m \u0219ablonul de distribu\u021bie a sarcinilor din articolul anterior, fie, dac\u0103 acesta nu se potrive\u0219te, scriem un planificator de sarcini personalizat, care va gestiona grupul de procesatori a\u0219a cum avem nevoie. <\/p>\n<p><\/p>\n<p>Punctul 3 necesit\u0103 extinderea \u0219ablonului pub-sub. Iar pentru realizare, dup\u0103 crearea punctului de schimb pub-sub, trebuie s\u0103 pornim suplimentar controlerul acestui punct \u00een cadrul serviciului nostru. Astfel, parc\u0103 scoatem logica de procesare a abon\u0103rii \u0219i dezabon\u0103rii din stratul de messaging \u00een implementarea users.<\/p>\n<p><\/p>\n<p>\u00cen cele din urm\u0103, decompunerea sarcinii a ar\u0103tat c\u0103 pentru a satisface cerin\u021bele trebuie s\u0103 pornim pe noduri diferite 5 instan\u021be ale serviciului \u0219i s\u0103 cre\u0103m o entitate suplimentar\u0103 \u2013 controlerul pub-sub, care este responsabil de abonare.<br \/>\nPentru a porni 5 procesatori nu este necesar s\u0103 schimb\u0103m codul serviciului. Singura ac\u021biune suplimentar\u0103 \u2013 configurarea regulilor de echilibrare pe punctul de schimb, despre care vom vorbi mai t\u00e2rziu.<br \/>\nDe asemenea, a ap\u0103rut o complexitate suplimentar\u0103: controlerul pub-sub \u0219i planificatorul de sarcini personalizat trebuie s\u0103 func\u021bioneze \u00eentr-o singur\u0103 instan\u021b\u0103. Din nou, serviciul de messaging, ca element fundamental, trebuie s\u0103 ofere un mecanism pentru alegerea unui lider.<\/p>\n<p><\/p>\n<h3 id=\"vybor-lidera\">Alegerea liderului<\/h3>\n<p><\/p>\n<p>\u00cen sistemele distribuite, alegerea liderului este o procedur\u0103 de numire a unui singur proces, responsabil pentru planificarea proces\u0103rii distribuite a unei anumite sarcini. <\/p>\n<p><\/p>\n<p>\u00cen sistemele care nu sunt predispuse la centralizare, se utilizeaz\u0103 algoritmi universali \u0219i algoritmi baza\u021bi pe consens, cum ar fi paxos sau raft.<br \/>\nDeoarece messaging este brokerul \u0219i elementul central, el cunoa\u0219te toate controlerele serviciului \u2013 candida\u021bii la pozi\u021bia de lider. Messaging poate numi un lider f\u0103r\u0103 a organiza o votare.<\/p>\n<p><\/p>\n<p>Toate serviciile, dup\u0103 ce au fost pornite \u0219i conectate la punctul de schimb, primesc un mesaj sistemic <code>#'$leader'{exchange = ?EXCHANGE, pid = LeaderPid, servers = Servers}<\/code>. \u00cen cazul \u00een care <code>LeaderPid<\/code> coincide cu <code>pid<\/code> procesul curent, acesta este numit lider, iar lista <code>Servers<\/code> include toate nodurile \u0219i parametrii lor.<br \/>\nAt the moment a new node joins and an active cluster node is disconnected, all service controllers receive <code>#'$slave_up'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts}<\/code> \u0219i <code>#'$slave_down'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts}<\/code> corespunz\u0103tor.<\/p>\n<p><\/p>\n<p>Thus, all components are aware of all changes, and at any given moment, there is guaranteed to be one leader in the cluster.<\/p>\n<p><\/p>\n<h2 id=\"posredniki\">Intermediaries<\/h2>\n<p><\/p>\n<p>To implement complex distributed processing processes, as well as in tasks of optimizing the existing architecture, it is convenient to use intermediaries.<br \/>\nTo avoid changing service codes and to handle, for example, tasks of additional processing, routing, or message logging, a proxy handler can be placed before the service, which will perform all the additional work.<\/p>\n<p><\/p>\n<p>A classic example of pub-sub optimization is a distributed application with a business core that generates update events, such as price changes in the market, and an access layer \u2014 N servers providing a websocket API for web clients.<br \/>\nIf we tackle it head-on, servicing the client looks as follows:<\/p>\n<p><\/p>\n<ul>\n<li>the client establishes connections with the platform. On the server side, where the traffic is terminated, a process is launched to service this connection.<\/li>\n<li>within the context of the servicing process, authorization and subscription to updates occur. The process calls the subscribe method for the topics.<\/li>\n<li>after the event is generated in the core, it is delivered to the processes servicing the connections.<\/li>\n<\/ul>\n<p><\/p>\n<p>Imagine we have 50,000 subscribers to the topic \"news\". The subscribers are evenly distributed across 5 servers. As a result, each update arriving at the exchange point will be replicated 50,000 times: 10,000 times on each server, corresponding to the number of subscribers on it. Not a very efficient scheme, right?<br \/>\nTo improve the situation, we will introduce a proxy that has the same name as the exchange point. The global name register should be able to return the nearest process by name, which is important.<\/p>\n<p><\/p>\n<p>We will run this proxy on the access layer servers, and all our processes servicing the websocket API will subscribe to it, rather than the original pub-sub exchange point in the core. The proxy subscribes to the core only in the case of unique subscriptions and replicates the incoming message to all its subscribers.<br \/>\nAs a result, only 5 messages will be sent between the core and the access servers, instead of 50,000.<\/p>\n<p><\/p>\n<h2 id=\"marshrutizaciya-i-balansirovka\">Routing and load balancing<\/h2>\n<p><\/p>\n<h3 id=\"req-resp\">Req-Resp<\/h3>\n<p><\/p>\n<p>In the current implementation of messaging, there are 7 request distribution strategies:<\/p>\n<p><\/p>\n<ul>\n<li><code>default<\/code>. Cererea este trimis\u0103 tuturor controlerilor.<\/li>\n<li><code>round-robin<\/code>. Se face o itera\u021bie \u0219i o distribu\u021bie ciclic\u0103 a cererilor \u00eentre controlere.<\/li>\n<li><code>consensus<\/code>. Controlerele care servesc serviciul se \u00eempart \u00een lider \u0219i subalterni. Cererile sunt trimise doar liderului.<\/li>\n<li><code>consensus &amp; round-robin<\/code>. \u00cen grup exist\u0103 un lider, dar cererile sunt distribuite \u00eentre to\u021bi membrii.<\/li>\n<li><code>sticky<\/code>. Se calculeaz\u0103 o func\u021bie hash \u0219i se leag\u0103 de un anumit procesor. Cererile ulterioare cu aceast\u0103 semn\u0103tur\u0103 ajung la acela\u0219i procesor.<\/li>\n<li><code>sticky-fun<\/code>. La ini\u021bializarea punctului de schimb se transmite suplimentar o func\u021bie de calculare a hash-ului pentru <code>sticky<\/code> balansare.<\/li>\n<li><code>distrac\u021bia<\/code>. Analogu cu sticky-fun, dar suplimentar putem redirec\u021biona, respinge sau preprocesa. <\/li>\n<\/ul>\n<p><\/p>\n<p>Strategia de distribu\u021bie este stabilit\u0103 la ini\u021bializarea punctului de schimb.<\/p>\n<p><\/p>\n<p>Pe l\u00e2ng\u0103 balansare, messagingul permite etichetarea entit\u0103\u021bilor. S\u0103 analiz\u0103m tipurile de etichete din sistem:<\/p>\n<p><\/p>\n<ul>\n<li>Eticheta de conectare. Permite \u00een\u021belegerea prin ce conexiune au venit evenimentele. Se folose\u0219te atunci c\u00e2nd procesul controlerului se conecteaz\u0103 la un singur punct de schimb, dar cu diferite chei de rutare. <\/li>\n<li>Eticheta de serviciu. Permite gruparea procesorilor pentru un singur serviciu \u0219i extinderea capacit\u0103\u021bilor de rutare \u0219i balansare. Pentru un model req-resp, rutarea este liniar\u0103. Trimitem o cerere la punctul de schimb, care apoi o transmite serviciului. Dar dac\u0103 vrem s\u0103 \u00eemp\u0103r\u021bim procesorii \u00een grupuri logice, aceast\u0103 \u00eemp\u0103r\u021bire se realizeaz\u0103 prin etichete. La specificarea unei etichete, cererea va fi direc\u021bionat\u0103 c\u0103tre un anumit grup de controlere.<\/li>\n<li>Eticheta cererii. Permite deosebirea r\u0103spunsurilor. Deoarece sistemul nostru este asincron, pentru a procesa r\u0103spunsurile serviciului trebuie s\u0103 avem posibilitatea de a specifica RequestTag la trimiterea cererii. Prin aceasta vom putea \u00een\u021belege la ce cerere a venit r\u0103spunsul.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"pub-sub\">Pub-sub<\/h3>\n<p><\/p>\n<p>Pentru pub-sub, lucrurile sunt pu\u021bin mai simple. Avem un punct de schimb la care se public\u0103 mesaje. Punctul de schimb distribuie mesajele \u00eentre abona\u021bi, care s-au abonat la cheile de rutare dorite (poate fi spus c\u0103 este un analog al temelor).<\/p>\n<p><\/p>\n<h2 id=\"masshtabiruemost-i-otkazoustoychivost\">Scalabilitate \u0219i disponibilitate<\/h2>\n<p><\/p>\n<p>Scalabilitatea sistemului \u00een ansamblu depinde \u00een totalitate de gradul de scalabilitate al straturilor \u0219i componentelor sistemului:<\/p>\n<p><\/p>\n<ul>\n<li>Serviciile se scaleaz\u0103 prin ad\u0103ugarea de noduri suplimentare \u00een cluster cu gestionarii acestui serviciu. \u00cen timpul exploat\u0103rii experimentale, se poate alege politica optim\u0103 de echilibrare.<\/li>\n<li>Serviciul de messaging, \u00een cadrul unui cluster separat, se scaleaz\u0103, \u00een general, fie prin mutarea punctelor de schimb foarte solicitate pe noduri separate ale clusterului, fie prin ad\u0103ugarea proceselor proxy \u00een zonele foarte solicitate ale clusterului.<\/li>\n<li>Scalabilitatea \u00eentregului sistem, ca caracteristic\u0103, depinde de flexibilitatea arhitecturii \u0219i de capacitatea de a combina unele clustere \u00eentr-o entitate logic\u0103 comun\u0103.<\/li>\n<\/ul>\n<p><\/p>\n<p>Succesul unui proiect depinde adesea de simplitatea \u0219i rapidezea scal\u0103rii. Messaging-ul \u00een actuala sa implementare cre\u0219te odat\u0103 cu aplica\u021bia. Chiar dac\u0103 ne lipsesc un cluster de 50-60 de ma\u0219ini, putem recurge la federare. Din p\u0103cate, tema feder\u0103rii dep\u0103\u0219e\u0219te limita acestui articol.<\/p>\n<p><\/p>\n<h2 id=\"rezervirovanie\">Rezervare<\/h2>\n<p><\/p>\n<p>\u00cen analiza echilibr\u0103rii \u00eenc\u0103rc\u0103turii, am discutat deja despre rezervarea controlerelor de servicii. Totu\u0219i, messaging-ul trebuie s\u0103 fie rezervat \u0219i el. \u00cen cazul c\u0103derii unui nod sau a unei ma\u0219ini, messaging-ul trebuie s\u0103 se recupereze automat, \u0219i asta \u00een cel mai scurt timp.<\/p>\n<p><\/p>\n<p>\u00cen proiectele mele, folosesc noduri suplimentare care preiau sarcina \u00een cazul unei c\u0103deri. \u00cen Erlang exist\u0103 o implementare standard a modului distribuit pentru aplica\u021biile OTP. Modul distribuit este exact ceea ce realizeaz\u0103 recuperarea \u00een cazul unei defec\u021biuni prin lansarea aplica\u021biei c\u0103zute pe un alt nod deja pornit. Procesul este transparent, dup\u0103 o defec\u021biune aplica\u021bia se mut\u0103 automat pe nodul de failover. Pute\u021bi citi mai multe despre aceast\u0103 func\u021bionalitate. <noindex><a rel=\"nofollow\" href=\"http:\/\/erlang.org\/doc\/design_principles\/distributed_applications.html\">aici<\/a><\/noindex>.<\/p>\n<p><\/p>\n<h2 id=\"proizvoditelnost\">Performan\u021b\u0103<\/h2>\n<p><\/p>\n<p>S\u0103 \u00eencerc\u0103m m\u0103car aproximativ s\u0103 compar\u0103m performan\u021ba rabbitmq cu messaging-ul nostru personalizat.<br \/>\nAm g\u0103sit <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.openstack.org\/developer\/performance-docs\/test_results\/mq\/rabbitmq\/cmsm\/index.html\">rezultatele oficiale<\/a><\/noindex> test\u0103rii rabbitmq de c\u0103tre echipa openstack.<\/p>\n<p><\/p>\n<p>\u00cen punctul 6.14.1.2.1.2.2 din documentul original este prezentat rezultatul RPC CAST:<br \/>\n<img decoding=\"async\" alt=\"Blocurile de baz\u0103 ale aplica\u021biilor distribuite. A doua aproximare\" src=\"\/wp-content\/uploads\/2019\/04\/95f615d241d70a4523fe3c400179b8e6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Preliminar, nu vom face nicio modificare suplimentar\u0103 \u00een nucleul sistemului de operare sau \u00een Erlang VM. Condi\u021biile pentru testare:<\/p>\n<p><\/p>\n<ul>\n<li>erl opts: +A1 +sbtu.<\/li>\n<li>Testul \u00een cadrul unui singur nod Erlang este derulat pe un laptop cu un vechi i7 \u00een versiune mobil\u0103.<\/li>\n<li>Testele de cluster se desf\u0103\u0219oar\u0103 pe servere cu re\u021bea de 10G.<\/li>\n<li>Codul ruleaz\u0103 \u00een containere docker. Re\u021beaua este \u00een modul NAT.<\/li>\n<\/ul>\n<p><\/p>\n<p>Codul testului:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">req_resp_bench(_) -&gt;\n  W = perftest:comprehensive(10000,\n    fun() -&gt;\n      messaging:request(?EXCHANGE, default, ping, self()),\n      receive\n        #'$msg'{message = pong} -&gt; ok\n      after 5000 -&gt;\n        throw(timeout)\n      end\n    end\n  ),\n  true = lists:any(fun(E) -&gt; E &gt;= 30000 end, W),\n  ok.<\/code><\/pre>\n<p><\/p>\n<p><em>Scenariul 1:<\/em> Testul se desf\u0103\u0219oar\u0103 pe un laptop cu un vechi i7 mobil. Testul, messaging \u0219i serviciul ruleaz\u0103 pe un singur nod \u00eentr-un singur container Docker:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Secven\u021bial 10000 de cicluri \u00een ~0 secunde (26987 cicluri\/s)\nSecven\u021bial 20000 de cicluri \u00een ~1 secund\u0103 (26915 cicluri\/s)\nSecven\u021bial 100000 de cicluri \u00een ~4 secunde (26957 cicluri\/s)\nParalel 2 100000 de cicluri \u00een ~2 secunde (44240 cicluri\/s)\nParalel 4 100000 de cicluri \u00een ~2 secunde (53459 cicluri\/s)\nParalel 10 100000 de cicluri \u00een ~2 secunde (52283 cicluri\/s)\nParalel 100 100000 de cicluri \u00een ~3 secunde (49317 cicluri\/s)<\/code><\/pre>\n<p><\/p>\n<p><em>Scenariul 2<\/em>: 3 noduri rul\u00e2nd pe ma\u0219ini diferite sub Docker (NAT).<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Secven\u021bial 10000 de cicluri \u00een ~1 secund\u0103 (8684 cicluri\/s)\nSecven\u021bial 20000 de cicluri \u00een ~2 secunde (8424 cicluri\/s)\nSecven\u021bial 100000 de cicluri \u00een ~12 secunde (8655 cicluri\/s)\nParalel 2 100000 de cicluri \u00een ~7 secunde (15160 cicluri\/s)\nParalel 4 100000 de cicluri \u00een ~5 secunde (19133 cicluri\/s)\nParalel 10 100000 de cicluri \u00een ~4 secunde (24399 cicluri\/s)\nParalel 100 100000 de cicluri \u00een ~3 secunde (34517 cicluri\/s)<\/code><\/pre>\n<p><\/p>\n<p>\u00cen toate cazurile, utilizarea procesorului nu a dep\u0103\u0219it 250%<\/p>\n<p><\/p>\n<h2 id=\"itogi\">Concluzii<\/h2>\n<p><\/p>\n<p>Sper c\u0103 acest ciclu nu pare a fi un dumping de con\u0219tiin\u021b\u0103 \u0219i c\u0103 experien\u021ba mea va aduce o real\u0103 beneficie at\u00e2t cercet\u0103torilor \u00een sisteme distribuite, c\u00e2t \u0219i practicienilor care sunt la \u00eenceputul construirii arhitecturilor distribuite pentru sistemele lor de afaceri \u0219i privesc cu interes la Erlang\/Elixir, dar se \u00eentreab\u0103 dac\u0103 merit\u0103...<\/p>\n<p><\/p>\n<p>Fotografie <noindex><a rel=\"nofollow\" href=\"https:\/\/unsplash.com\/photos\/Q4bmoSPJM18\">@chuttersnap<\/a><\/noindex><\/p>\n<p class=\"for_users_only_msg\">Numai utilizatorii \u00eenregistra\u021bi pot participa la sondaj. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Conecta\u021bi-v\u0103<\/a><\/noindex>, v\u0103 rug\u0103m.<\/p>\n<h2 class=\"default-block__polling-title\">Ce teme ar trebui s\u0103 discut detaliat \u00een cadrul ciclului \u201eExperiment VTrade\u201d?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Teoria: Pie\u021bele, ordinele \u0219i perioada lor de valabilitate: DAY, GTD, GTC, IOC, FOK, MOO, MOC, LOO, LOC<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Cartea de ordine. Teoria \u0219i practica implement\u0103rii c\u0103r\u021bii cu grup\u0103ri<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Vizualizarea tranzac\u021biilor: Tick-uri, bare, rezolu\u021bii. Cum s\u0103 stoca\u021bi \u0219i cum s\u0103 asambla\u021bi<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Backoffice. Planificare \u0219i dezvoltare. Controlul angaja\u021bilor \u0219i investigarea incidentelor<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    API. Stud\u0103m ce interfe\u021be sunt necesare \u0219i cum s\u0103 le implement\u0103m<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Stocarea informa\u021biilor: PostgreSQL, Timescale, Tarantool \u00een sistemele de tranzac\u021bionare<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Reactivitatea \u00een sistemele de tranzac\u021bionare<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Altele. Voi scrie \u00een comentarii<\/p>\n<\/li>\n<\/ul>\n<p>    Au votat 6 utilizatori. 4 utilizatori s-au ab\u021binut.<br \/>\n<br \/>Sursa: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446344\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0410\u043d\u043e\u043d\u0441 \u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043b\u0435\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f: \u201c\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 VTrade\u201d \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c. \u0412 \u0446\u0438\u043a\u043b\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u0430 \u0442\u0435\u043e\u0440\u0438\u044f \u0438 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0431\u0438\u0440\u0436\u0438, \u0430\u0443\u043a\u0446\u0438\u043e\u043d\u0430 \u0438 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u0430. \u0412 \u043a\u043e\u043d\u0446\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u043f\u0440\u043e\u0433\u043e\u043b\u043e\u0441\u043e\u0432\u0430\u0442\u044c \u0437\u0430 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0435 \u0432\u0430\u043c \u0442\u0435\u043c\u044b. \u042d\u0442\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0449\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0446\u0438\u043a\u043b\u0430 \u043f\u043e \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u043c [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":23092,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-31124","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0410\u043d\u043e\u043d\u0441 \u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043b\u0435\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f: \u201c\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 VTrade\u201d \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"ro_RO\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0421\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0412\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0410\u043d\u043e\u043d\u0441 \u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043b\u0435\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f: \u201c\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 VTrade\u201d \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:39:36+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:39:36+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Blocurile de construc\u021bie ale aplica\u021biilor distribuite. A doua aproximare | ProHoster","description":"Anun\u021b Colegi, \u00een mijlocul verii pl\u0103nuiesc s\u0103 lansez un nou ciclu de articole despre proiectarea sistemelor de servicii masive: \u201eExperiment VTrade\u201d - o \u00eencercare de a scrie un cadru pentru tranzac\u021bionare.","canonical_url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"ro_RO","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0421\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0431\u043b\u043e\u043a\u0438 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439. \u0412\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 | ProHoster","og:description":"\u0410\u043d\u043e\u043d\u0441 \u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0432 \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 \u043b\u0435\u0442\u0430 \u044f \u043f\u043b\u0430\u043d\u0438\u0440\u0443\u044e \u0432\u044b\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0446\u0438\u043a\u043b \u0441\u0442\u0430\u0442\u0435\u0439 \u043f\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c \u043c\u0430\u0441\u0441\u043e\u0432\u043e\u0433\u043e \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f: \u201c\u042d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442 VTrade\u201d \u2014 \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0434\u043b\u044f \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445.","og:url":"https:\/\/prohoster.info\/ro\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:39:36+00:00","article:modified_time":"2019-10-31T18:39:36+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"31124","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 04:39:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:22:34","updated":"2026-01-21 04:39:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/31124","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/comments?post=31124"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/posts\/31124\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media\/23092"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/media?parent=31124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/categories?post=31124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/ro\/wp-json\/wp\/v2\/tags?post=31124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}