{"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\/da\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","title":{"rendered":"Bygningsblokke for distribuerede applikationer. Andet n\u00e6rmere kig","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><strong>Annonce<\/strong><\/p>\n<p><\/p>\n<p><em>Kollegaer, midt p\u00e5 sommeren planl\u00e6gger jeg at udgive endnu en r\u00e6kke artikler om design af systemer til massebetjening: \u201cEksperiment VTrade\u201d \u2014 et fors\u00f8g p\u00e5 at skrive et framework til handelssystemer. I serien vil teorien og praksis for opbygning af en b\u00f8rs, auktion og butik blive dr\u00f8ftet. I slutningen af artiklen foresl\u00e5r jeg at stemme om de emner, der interesserer jer mest.<br \/>\n<\/em><\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Bygningsblokke for distribuerede applikationer. Andet n\u00e6rmere kig\" src=\"\/wp-content\/uploads\/2019\/04\/358996733e805327b587176f4f992aea.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Dette er den afsluttende artikel i r\u00e6kken om distribuerede reaktive applikationer p\u00e5 Erlang\/Elixir. I <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446028\/\">den f\u00f8rste artikel<\/a><\/noindex> kan man finde de teoretiske grundlag for reaktiv arkitektur. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446108\/\">Den anden artikel<\/a><\/noindex> illustrerer de grundl\u00e6ggende m\u00f8nstre og mekanismer til opbygning af s\u00e5danne systemer.<\/p>\n<p><\/p>\n<p>I dag vil vi tage fat p\u00e5 sp\u00f8rgsm\u00e5l ang\u00e5ende udviklingen af kodebasen og projekterne generelt. <\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"organizaciya-servisov\">Organisering af tjenester<\/h2>\n<p><\/p>\n<p>I det virkelige liv, n\u00e5r man udvikler en tjeneste, m\u00e5 man ofte forene flere interaktionsm\u00f8nstre i \u00e9n controller. For eksempel skal tjenesten users, som l\u00f8ser opgaver med at administrere brugerprofiler for projektet, h\u00e5ndtere foresp\u00f8rgsler req-resp og informere om opdateringer af profiler gennem pub-sub. Denne situation er ret simpel: for messaging st\u00e5r der \u00e9n controller, som implementerer logikken for tjenesten og offentligg\u00f8r opdateringer.<\/p>\n<p><\/p>\n<p>Situationen bliver mere kompliceret, n\u00e5r vi skal implementere en fejltolerant distribueret tjeneste. Antag, at kravene til users er \u00e6ndret: <\/p>\n<p><\/p>\n<ol>\n<li>nu skal tjenesten h\u00e5ndtere foresp\u00f8rgsler p\u00e5 5 noder i klyngen, <\/li>\n<li>have mulighed for at udf\u00f8re baggrundsbehandlingsopgaver, <\/li>\n<li>samt v\u00e6re i stand til dynamisk at administrere lister over abonnementer p\u00e5 opdateringer af profiler.<\/li>\n<\/ol>\n<p><\/p>\n<p><em>Bem\u00e6rk:<\/em> Sp\u00f8rgsm\u00e5let om konsistent lagring og replikering af data vil vi ikke behandle. Antag, at disse sp\u00f8rgsm\u00e5l er blevet l\u00f8st tidligere, og at systemet allerede har et p\u00e5lideligt og skalerbart lag for lagring, og at handlere har mekanismer til interaktion med det.<\/p>\n<p><\/p>\n<p>Det formelle beskrivelser af tjenesten users er blevet mere kompliceret. Set fra programm\u00f8rens perspektiv, takket v\u00e6re brugen af messaging, er \u00e6ndringerne minimale. For at im\u00f8dekomme det f\u00f8rste krav skal vi konfigurere belastningsbalancering ved udvekslingspunktet req-resp. <\/p>\n<p><\/p>\n<p>Kravet for behandling af baggrundsopgaver opst\u00e5r ofte. I users kan dette v\u00e6re kontrol af brugerens dokumenter, behandling af uploadet multimedie, eller synkronisering af data med sociale medier. Disse opgaver skal p\u00e5 en eller anden m\u00e5de fordeles inden for klyngen og kontroleres. Derfor har vi to l\u00f8sningsmuligheder: enten bruge skabelonen til opgavefordeling fra den tidligere artikel, eller, hvis den ikke passer, skrive en brugerdefineret opgavestyrer, der p\u00e5 den n\u00f8dvendige m\u00e5de skal h\u00e5ndtere puljen af behandlere. <\/p>\n<p><\/p>\n<p>Punkt 3 kr\u00e6ver en udvidelse af pub-sub skabelonen. Og for at implementere dette, efter oprettelsen af pub-sub udvekslingspunktet, skal vi yderligere starte controllere for dette punkt inden for vores service. S\u00e5dan set tager vi som om logikken for behandling af abonnementer og afmeldinger ud af messaging-laget og ind i implementationen af users.<\/p>\n<p><\/p>\n<p>Som et resultat viste dekompositionen af opgaven, at for at opfylde kravene skal vi k\u00f8re 5 instanser af servicen p\u00e5 forskellige noder og oprette en ekstra enhed \u2013 en pub-sub controller, der er ansvarlig for abonnementet.<br \/>\nFor at starte 5 behandlere kr\u00e6ves der ikke \u00e6ndringer i servicekoden. Den eneste yderligere handling er at konfigurere balanceringsreglerne p\u00e5 udvekslingspunktet, hvilket vi vil tale mere om lidt senere.<br \/>\nDer opstod ogs\u00e5 en ekstra kompleksitet: pub-sub controllere og den brugerdefinerede opgavestyrer skal k\u00f8re i en enkelt instans. Igen, messaging servicen, som det fundamentale element, skal levere en mekanisme til valg af leder.<\/p>\n<p><\/p>\n<h3 id=\"vybor-lidera\">Valg af leder<\/h3>\n<p><\/p>\n<p>I distribuerede systemer er valg af leder \u2013 proceduren for udn\u00e6vnelse af en enkelt proces, der er ansvarlig for planl\u00e6gning af distribueret behandling af en eller anden belastning. <\/p>\n<p><\/p>\n<p>I systemer, der ikke er tilb\u00f8jelige til centralisering, anvendes universelle algoritmer og konsensusbaserede algoritmer, s\u00e5som Paxos eller Raft.<br \/>\nDa messaging er broker og det centrale element, kender det til alle controllere af servicen \u2013 kandidater til lederskab. Messaging kan udn\u00e6vne en leder uden afholdelse af afstemning.<\/p>\n<p><\/p>\n<p>Alle tjenester efter start og tilslutning til udvekslingspunktet modtager en systemmeddelelse <code>#'$leader'{exchange = ?EXCHANGE, pid = LeaderPid, servers = Servers}<\/code>. I tilf\u00e6lde af at <code>LeaderPid<\/code> stemmer overens med <code>pid<\/code> den nuv\u00e6rende proces, udn\u00e6vnes han som leder, og listen over <code>Servers<\/code> inkluderer alle noder og deres parametre.<br \/>\nN\u00e5r en ny node opst\u00e5r eller en fungerende node i klyngen deaktiveres, modtager alle servicekontrollere <code>#'$slave_up'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts}<\/code> og <code>#'$slave_down'{exchange = ?EXCHANGE, pid = SlavePid, options = SlaveOpts}<\/code> henholdsvis.<\/p>\n<p><\/p>\n<p>Dermed er alle komponenter informeret om alle \u00e6ndringer, og der er altid \u00e9n leder i klyngen p\u00e5 ethvert givent tidspunkt.<\/p>\n<p><\/p>\n<h2 id=\"posredniki\">Mellemled<\/h2>\n<p><\/p>\n<p>For at implementere komplekse distribuerede behandlingsprocesser samt ved optimering af allerede eksisterende arkitektur kan det v\u00e6re praktisk at anvende mellemled.<br \/>\nFor at undg\u00e5 at \u00e6ndre services koden og for at l\u00f8se f.eks. opgaver som yderligere behandling, routing eller logning af beskeder, kan man aktivere en proxybehandler f\u00f8r servicen, som udf\u00f8rer alt det ekstra arbejde.<\/p>\n<p><\/p>\n<p>Et klassisk eksempel p\u00e5 optimalisering af pub-sub er en distribueret applikation med et forretningskerne, der genererer opdateringsbegivenheder, som f.eks. \u00e6ndring af pris p\u00e5 markedet, og et adgangslag - N servere, der tilbyder websocket API til webklienter.<br \/>\nHvis man ser p\u00e5 det direkte, ser betjeningen af klienten s\u00e5ledes ud:<\/p>\n<p><\/p>\n<ul>\n<li>klienten opretter forbindelse til platformen. P\u00e5 serversiden, hvor trafikken termineres, startes en proces, der h\u00e5ndterer denne forbindelse.<\/li>\n<li>i konteksten af den betjente proces finder autorisation og tilmelding til opdateringer sted. Processen kalder metoden subscribe for emnerne.<\/li>\n<li>efter generering af en begivenhed i kernen leveres den til processerne, der betjener forbindelserne.<\/li>\n<\/ul>\n<p><\/p>\n<p>Lad os forestille os, at vi har 50000 abonnenter p\u00e5 emnet \"nyheder\". Abonnenterne er j\u00e6vnt fordelt p\u00e5 5 servere. I sidste ende vil hver opdatering, der n\u00e5r frem til udvekslingspunktet, blive replikeret 50000 gange: 10000 gange p\u00e5 hver server, afh\u00e6ngigt af antallet af abonnenter der.<br \/>\nFor at forbedre situationen, lad os introducere en proxy, der har det samme navn som udvekslingspunktet. Registratoren for globale navne skal kunne returnere den n\u00e6rmeste proces efter navn, hvilket er vigtigt.<\/p>\n<p><\/p>\n<p>Lad os starte denne proxy p\u00e5 serverne i adgangslaget, og alle vores processer, der betjener websocket api, vil tilmelde sig den, og ikke det oprindelige pub-sub udvekslingspunkt i kernen. Proxyen tilmelder sig kernen kun ved unik tilmelding og replikerer de indkommende beskeder til alle sine abonnenter.<br \/>\nI sidste ende vil der blive sendt 5 beskeder mellem kernen og adgangsserverne i stedet for 50000.<\/p>\n<p><\/p>\n<h2 id=\"marshrutizaciya-i-balansirovka\">Routing og belastningsfordeling<\/h2>\n<p><\/p>\n<h3 id=\"req-resp\">Req-Resp<\/h3>\n<p><\/p>\n<p>I den nuv\u00e6rende implementering af messaging findes der 7 strategier til fordeling af anmodninger:<\/p>\n<p><\/p>\n<ul>\n<li><code>default<\/code>. Anmodningen sendes til alle controllere.<\/li>\n<li><code>rundt-rundt<\/code>. Der foretages en iteration og cyklisk fordeling af anmodninger mellem controllere.<\/li>\n<li><code>konsensus<\/code>. Der er kontrollere, der betjener tjenesten, opdelt i leder og tilh\u00e6ngere. Anmodninger sendes kun til lederen.<\/li>\n<li><code>konsensus &amp; rundt-rundt<\/code>. Gruppen har en leder, men anmodninger fordeles mellem alle medlemmer.<\/li>\n<li><code>sticky<\/code>. En hashfunktion beregnes og fastl\u00e6gges for en bestemt behandler. Efterf\u00f8lgende anmodninger med denne signatur g\u00e5r til den samme behandler.<\/li>\n<li><code>sticky-fun<\/code>. Ved initialisering af udvekslingspunktet overf\u00f8res der desuden en hashberegningsfunktion til <code>sticky<\/code> balancering.<\/li>\n<li><code>sjov<\/code>. Ligner sticky-fun, men herudover kan du omdirigere, afvise eller forbehandle det. <\/li>\n<\/ul>\n<p><\/p>\n<p>Fordelingsstrategien angives ved initialisering af udvekslingspunktet.<\/p>\n<p><\/p>\n<p>Udover balancering tillader messaging at tagge entiteter. Lad os se p\u00e5 typerne af tags i systemet:<\/p>\n<p><\/p>\n<ul>\n<li>Forbindelsestag. G\u00f8r det muligt at forst\u00e5, gennem hvilken forbindelse h\u00e6ndelserne kom. Anvendes, n\u00e5r controllerprocessen forbinder til et enkelt udvekslingspunkt, men med forskellige routing-n\u00f8gler. <\/li>\n<li>Servicetag. G\u00f8r det muligt at gruppere behandlere for en enkelt service og udvide mulighederne for routing og balancing. For req-resp m\u00f8nsteret er routing line\u00e6r. Vi sender en anmodning til udvekslingspunktet, som derefter sender den til tjenesten. Men hvis vi har brug for at opdele behandlere i logiske grupper, s\u00e5 sker opdelingen ved hj\u00e6lp af tags. N\u00e5r du angiver et tag, vil anmodningen blive dirigeret til en specifik gruppe controllere.<\/li>\n<li>Anmodningstag. G\u00f8r det muligt at skelne mellem svar. Da vores system er asynkront, skal svarene fra tjenesten have mulighed for at angive RequestTag ved afsendelse af anmodningen. Ved dette kan vi forst\u00e5, hvilket svar vi har modtaget p\u00e5 vores anmodning.<\/li>\n<\/ul>\n<p><\/p>\n<h3 id=\"pub-sub\">Pub-sub<\/h3>\n<p><\/p>\n<p>For pub-sub er det lidt lettere. Vi har et udvekslingspunkt, hvor meddelelser offentligg\u00f8res. Udvekslingspunktet fordeler meddelelser mellem abonnenterne, der har tilmeldt sig de \u00f8nskede routing-n\u00f8gler (man kan sige, at det svarer til emner).<\/p>\n<p><\/p>\n<h2 id=\"masshtabiruemost-i-otkazoustoychivost\">Skal\u00e9rbarhed og fejlmodstand<\/h2>\n<p><\/p>\n<p>Systemets samlede skal\u00e9rbarhed afh\u00e6nger af graden af skal\u00e9rbarhed i systemets lag og komponenter:<\/p>\n<p><\/p>\n<ul>\n<li>Tjenester skaleres ved at tilf\u00f8je ekstra noder med behandlere af denne tjeneste til klyngen. I l\u00f8bet af praktisk brug kan den optimale balanceringspolitik v\u00e6lges.<\/li>\n<li>Selve messaging-tjenesten inden for en separat klynge skaleres generelt enten ved at flytte s\u00e6rligt belastede udvekslingspunkter til separate noder i klyngen eller ved at tilf\u00f8je proxy-processer i s\u00e6rligt belastede omr\u00e5der af klyngen.<\/li>\n<li>Skalerbarheden af hele systemet som egenskab afh\u00e6nger af fleksibiliteten i arkitekturen og muligheden for at samle separate klynger til en samlet logisk enhed.<\/li>\n<\/ul>\n<p><\/p>\n<p>Simpliciteten og hastigheden af skalerbarhed afh\u00e6nger ofte af projektets succes. Messaging i den nuv\u00e6rende udf\u00f8relse vokser sammen med applikationen. Selv hvis vi mangler en klynge med 50-60 maskiner, kan vi ty til federation. Desv\u00e6rre ligger emnet omkring federation uden for rammerne af denne artikel.<\/p>\n<p><\/p>\n<h2 id=\"rezervirovanie\">Redundans<\/h2>\n<p><\/p>\n<p>N\u00e5r vi taler om belastningsbalancering, har vi allerede diskuteret reservemuligheder for tjenestestyringskontrollere. Men messaging b\u00f8r ogs\u00e5 v\u00e6re reserveret. I tilf\u00e6lde af et nodetab eller maskinfejl, skal messaging automatisk gendannes, og det skal ske hurtigst muligt.<\/p>\n<p><\/p>\n<p>I mine projekter bruger jeg ekstra noder, der overtager belastningen i tilf\u00e6lde af et nedbrud. I Erlang findes der en standardimplementering af distribueret tilstand for OTP-applikationer. Distributed mode genopretter netop i tilf\u00e6lde af fejl ved at starte den nedlagte applikation p\u00e5 en anden, forudstartet node. Processen er gennemsigtig, efter et nedbrud flyttes applikationen automatisk til failover-noden. Du kan l\u00e6se mere om denne funktionalitet. <noindex><a rel=\"nofollow\" href=\"http:\/\/erlang.org\/doc\/design_principles\/distributed_applications.html\">her<\/a><\/noindex>.<\/p>\n<p><\/p>\n<h2 id=\"proizvoditelnost\">Ydeevne<\/h2>\n<p><\/p>\n<p>Lad os fors\u00f8ge at sammenligne ydeevnen af rabbitmq og vores tilpassede messaging rimeligt.<br \/>\nJeg fandt <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.openstack.org\/developer\/performance-docs\/test_results\/mq\/rabbitmq\/cmsm\/index.html\">de officielle resultater<\/a><\/noindex> af rabbitmq-testen fra openstack-teamet.<\/p>\n<p><\/p>\n<p>I punkt 6.14.1.2.1.2.2 i det originale dokument pr\u00e6senteres resultatet af RPC CAST:<br \/>\n<img decoding=\"async\" alt=\"Bygningsblokke for distribuerede applikationer. Andet n\u00e6rmere kig\" src=\"\/wp-content\/uploads\/2019\/04\/95f615d241d70a4523fe3c400179b8e6.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Forud for testene vil vi ikke foretage yderligere indstillinger i OS-kernen eller Erlang VM. Betingelserne for testen:<\/p>\n<p><\/p>\n<ul>\n<li>erl opts: +A1 +sbtu.<\/li>\n<li>Testen k\u00f8rer i en enkelt Erlang-node p\u00e5 en b\u00e6rbar computer med en \u00e6ldre mobil i7.<\/li>\n<li>Klyngetestene k\u00f8rer p\u00e5 servere med 10G netv\u00e6rk.<\/li>\n<li>Koden k\u00f8rer i docker-containere. Netv\u00e6rket er i NAT-tilstand.<\/li>\n<\/ul>\n<p><\/p>\n<p>Testkoden:<\/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>Scenario 1:<\/em> Testet k\u00f8rer p\u00e5 en b\u00e6rbar med en gammel i7 mobiludgave. Test, messaging og service k\u00f8rer p\u00e5 en node i samme docker-container:<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Sekventielle 10000 cyklusser p\u00e5 ~0 sekunder (26987 cyklusser\/s)\nSekventielle 20000 cyklusser p\u00e5 ~1 sekund (26915 cyklusser\/s)\nSekventielle 100000 cyklusser p\u00e5 ~4 sekunder (26957 cyklusser\/s)\nParallel 2 100000 cyklusser p\u00e5 ~2 sekunder (44240 cyklusser\/s)\nParallel 4 100000 cyklusser p\u00e5 ~2 sekunder (53459 cyklusser\/s)\nParallel 10 100000 cyklusser p\u00e5 ~2 sekunder (52283 cyklusser\/s)\nParallel 100 100000 cyklusser p\u00e5 ~3 sekunder (49317 cyklusser\/s)<\/code><\/pre>\n<p><\/p>\n<p><em>Scenario 2<\/em>: 3 noder k\u00f8res p\u00e5 forskellige maskiner under docker (NAT).<\/p>\n<p><\/p>\n<pre><code class=\"plaintext\">Sekventielle 10000 cyklusser p\u00e5 ~1 sekund (8684 cyklusser\/s)\nSekventielle 20000 cyklusser p\u00e5 ~2 sekunder (8424 cyklusser\/s)\nSekventielle 100000 cyklusser p\u00e5 ~12 sekunder (8655 cyklusser\/s)\nParallel 2 100000 cyklusser p\u00e5 ~7 sekunder (15160 cyklusser\/s)\nParallel 4 100000 cyklusser p\u00e5 ~5 sekunder (19133 cyklusser\/s)\nParallel 10 100000 cyklusser p\u00e5 ~4 sekunder (24399 cyklusser\/s)\nParallel 100 100000 cyklusser p\u00e5 ~3 sekunder (34517 cyklusser\/s)<\/code><\/pre>\n<p><\/p>\n<p>I alle tilf\u00e6lde oversteg CPU-udnyttelsen ikke 250%<\/p>\n<p><\/p>\n<h2 id=\"itogi\">Resum\u00e9<\/h2>\n<p><\/p>\n<p>Jeg h\u00e5ber, at denne cyklus ikke virker som en str\u00f8m af bevidsthed, og at min erfaring vil bringe reel v\u00e6rdi b\u00e5de til forskere inden for distribuerede systemer og praktikere, der er i starten af at bygge distribuerede arkitekturer til deres forretningssystemer og som ser med interesse p\u00e5 Erlang\/Elixir, men som er i tvivl om, det er v\u00e6rd at...<\/p>\n<p><\/p>\n<p>Foto <noindex><a rel=\"nofollow\" href=\"https:\/\/unsplash.com\/photos\/Q4bmoSPJM18\">@chuttersnap<\/a><\/noindex><\/p>\n<p class=\"for_users_only_msg\">Kun registrerede brugere kan deltage i unders\u00f8gelsen. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Log ind<\/a><\/noindex>, please.<\/p>\n<h2 class=\"default-block__polling-title\">Hvilke emner b\u00f8r jeg belyse mest detaljeret i cyklussen \u201cEksperiment VTrade\u201d?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Teori: Markeder, ordrer og deres gyldighed: DAY, GTD, GTC, IOC, FOK, MOO, MOC, LOO, LOC<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Ordrebog. Teori og praksis for implementering af bogen med grupperinger<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Visualisering af handel: Ticks, barer, opl\u00f8sninger. Hvordan man opbevarer og sammenk\u00e6der<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Backoffice. Planl\u00e6gning og udvikling. Kontrol af medarbejdere og efterforskning af h\u00e6ndelser<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    API. Vi ser p\u00e5 hvilke interfaces der er n\u00f8dvendige, og hvordan de implementeres<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Opbevaring af information: PostgreSQL, Timescale, Tarantool i handelssystemer<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Reaktivitet i handelssystemer<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Andet. Jeg skriver i kommentarerne<\/p>\n<\/li>\n<\/ul>\n<p>    6 brugere har stemt. 4 brugere har undladt at stemme.<br \/>\n<br \/>Kilde: <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.3 - 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\/da\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"da_DK\" \/>\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\/da\/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\udd47Byggeklodser i distribuerede applikationer. Andet n\u00e6rmere | ProHoster","description":"Annonce Kolleger, i midten af sommeren planl\u00e6gger jeg at udgive endnu en r\u00e6kke artikler om design af massetjenestesystemer: \u201cEksperiment VTrade\u201d \u2014 et fors\u00f8g p\u00e5 at skrive et framework til handel.","canonical_url":"https:\/\/prohoster.info\/da\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-vtoroe-priblizhenie","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"da_DK","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\/da\/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\/da\/wp-json\/wp\/v2\/posts\/31124","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/comments?post=31124"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/posts\/31124\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media\/23092"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/media?parent=31124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/categories?post=31124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/da\/wp-json\/wp\/v2\/tags?post=31124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}