{"id":30908,"date":"2019-10-31T21:38:07","date_gmt":"2019-10-31T18:38:07","guid":{"rendered":"https:\/\/prohoster.info\/blog\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie\/"},"modified":"2019-10-31T21:38:07","modified_gmt":"2019-10-31T18:38:07","slug":"stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie","status":"publish","type":"post","link":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie","title":{"rendered":"Jaotatud rakenduste ehitusplokkide. Esimene l\u00e4henemine","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokkide. Esimene l\u00e4henemine\" src=\"\/wp-content\/uploads\/2019\/04\/7ef485e452075775ce317b557671274c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Eelmisel <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446028\/\">artiklis<\/a><\/noindex> Me k\u00e4sitlesime reaktiivse arhitektuuri teoreetilisi aluseid. On aeg r\u00e4\u00e4kida andmevoogudest, reaktiivsete Erlang\/Elixir s\u00fcsteemide elluviimise viisidest ja nende s\u00f5numivahetuse mustritest:<\/p>\n<p><\/p>\n<ul>\n<li>P\u00e4ring-vastus<\/li>\n<li>P\u00e4ring-osaline vastus<\/li>\n<li>Vastus p\u00e4ringu alusel<\/li>\n<li>Avalda-telli<\/li>\n<li>P\u00f6\u00f6rdprotsesside \u00fclekandmine<\/li>\n<li>\u00dclesannete jaotamine<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"soa-msa-i-obmen-soobscheniyami\">SOA, MSA ja s\u00f5numivahetus<\/h2>\n<p><\/p>\n<p>SOA ja MSA on s\u00fcsteemiarhitektuurid, mis m\u00e4\u00e4ravad s\u00fcsteemide \u00fclesehituse reeglid, samas kui s\u00f5numivahetus pakub nende rakendamiseks primitiive.<\/p>\n<p><\/p>\n<p>Ma ei soovi propageerida \u00fchte ega teist s\u00fcsteemide arhitektuuri. Ma olen selle poolt, et rakendada konkreetsele projektile ja ettev\u00f5ttele maksimaalselt efektiivseid ja kasulikke praktikaid. Millist paradigmat me ei valiks, on s\u00fcsteemide plokkide loomine parem Unix-way j\u00e4rgi: komponentide minimaalne seos, mis vastutavad eraldi entiteetide eest. API meetodid teevad entiteetidega v\u00f5imalikult lihtsaid toiminguid.<\/p>\n<p><\/p>\n<p>S\u00f5numivahetus \u2013 nagu nimest j\u00e4reldub \u2013 on s\u00f5numi vahendaja. Selle p\u00f5hieesm\u00e4rk on s\u00f5numite vastuv\u00f5tt ja edastamine. See vastutab teabe saatmise liideste, loogiliste teabeedastuskanalite loomise, marsruutimise ja tasakaalustamise ning s\u00fcsteemitasandi rikete t\u00f6\u00f6tlemise eest.<br \/>\nArendatav s\u00f5numivahetus ei p\u00fc\u00fca konkureerida rabbitmq-ga ega asendada seda. Selle peamised omadused on:<\/p>\n<p><\/p>\n<ul>\n<li>Jagatud olemus.<br \/>\nVahetuspunktid saab luua k\u00f5ikides klastriteosades, maksimaalselt l\u00e4hedale koodile, mis neid kasutab.<\/li>\n<li>Lihtsus.<br \/>\nMinimaalne malli koodi ja kasutusmugavuse suund.<\/li>\n<li>Parim j\u00f5udlus.<br \/>\nMe ei p\u00fc\u00fca kopeerida rabbitmq funktsionaalsust, vaid eristame ainult arhitektuurilist ja transpordikihti, mille integreerimine OTP-sse on v\u00f5imalikult lihtne, minimeerides kulusid.<\/li>\n<li>Paindlikkus.<br \/>\nIga teenus v\u00f5ib h\u00f5lmata mitmeid s\u00f5numivahetuse mustreid.<\/li>\n<li>T\u00f5rketaluvus, mis on sisustatud disaini.<\/li>\n<li>Skaleeritavus.<br \/>\nS\u00f5numivahetus kasvab koos rakendusega. Koormuse suurenedes saate vahetuspunktid eraldi masinatesse viia.<\/li>\n<\/ul>\n<p><\/p>\n<p><em>M\u00e4rkus.<\/em> Koodiorganisatsiooni seisukohalt sobivad keerukate s\u00fcsteemide jaoks Erlangi\/Elixiri metaprojektid h\u00e4sti. Kogu projekti kood asub \u00fches hoidlas \u2012 katuseprojekti all. Sellega samal ajal on mikroteenused maksimaalselt eraldatud ja teevad lihtsaid operatsioone, mis vastavad eraldi entiteedile. Sellise l\u00e4henemisega on lihtne toetada kogu s\u00fcsteemi API-d, h\u00f5lpsasti teha muudatusi ja mugavalt kirjutada \u00fcksus- ja integreerimisteste.<\/p>\n<p><\/p>\n<p>S\u00fcsteemi komponendid suhtlevad vahetult v\u00f5i l\u00e4bi maakleri. Messaging'u seisukohalt on igal teenusel mitu eluetappi:<\/p>\n<p><\/p>\n<ul>\n<li>Teenuse initsialiseerimine.<br \/>\nSellel etapil toimub teenuse k\u00e4itamisprotsessi ja s\u00f5ltuvuste konfigureerimine ja k\u00e4ivitamine.<\/li>\n<li>Vahetuspunkti loomine.<br \/>\nTeenusel v\u00f5ib olla staatiline vahetuspunkt, mis on m\u00e4\u00e4ratud s\u00f5lme konfiguratsioonis, v\u00f5i v\u00f5ib see luua vahetuspunktid d\u00fcnaamiliselt. <\/li>\n<li>Teenuse registreerimine.<br \/>\nKuna teenus peab teenindama p\u00e4ringuid, tuleb see registreerida vahetuspunktis.<\/li>\n<li>Normaalne toimimine.<br \/>\nTeenuse kasulik t\u00f6\u00f6.<\/li>\n<li>T\u00f6\u00f6 l\u00f5petamine.<br \/>\nT\u00f6\u00f6 l\u00f5petamiseks on kaks varianti: regulaarne ja avarii. Regulaarse l\u00f5petamise korral katkestatakse teenus vahetuspunktist ja peatub. Avarii korral t\u00e4idab messaging \u00fche t\u00f5rke t\u00f6\u00f6tlemise stsenaariumidest.<\/li>\n<\/ul>\n<p><\/p>\n<p>See tundub \u00fcsna keeruline, kuid koodis pole k\u00f5ik nii hirmus. Koodin\u00e4idised koos kommentaaridega esitatakse malle k\u00e4sitlevas osas veidi hiljem.<\/p>\n<p><\/p>\n<h2 id=\"exchanges\">Vahetused<\/h2>\n<p><\/p>\n<p>Vahetuspunkt on messaging'u protsess, mis rakendab loogikat komponentide vahelise suhtluse jaoks vastavalt s\u00f5numivahetuse malli. K\u00f5ikidel allpool esitatud n\u00e4idistel suhtlevad komponendid vahetuspunktide kaudu, mille kombinatsioon moodustab messaging'u.<\/p>\n<p><\/p>\n<h2 id=\"message-exchange-patterns-meps\">S\u00f5numivahetuse mustrid (MEP-d)<\/h2>\n<p><\/p>\n<p>Globaalsete mustrite kohaselt v\u00f5ib vahetused jaotada kahepoolsed ja \u00fchekordsed. Esimene neist eeldab vastust saabunud s\u00f5numile, teine aga mitte. Kliendi-serveri arhitektuuris on klassikaliseks n\u00e4iteks kahepoolne mustri malli Request-response. Vaatame mustrit ja selle modifikatsioone.<\/p>\n<p><\/p>\n<h3 id=\"requestresponse-ili-rpc\">Request\u2013response v\u00f5i RPC<\/h3>\n<p><\/p>\n<p>RPC-d kasutatakse siis, kui me peame saama vastuse teisest protsessist. See protsess v\u00f5ib t\u00f6\u00f6tada samal s\u00f5lmel v\u00f5i asuda teisel kontinendil. Allpool on esitatud skeem kliendi ja <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/et\/server\/dts-los-angeles\/\"   title=\"serverilt\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"3483\">serverilt<\/a> vahetuspunkti kaudu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokkide. Esimene l\u00e4henemine\" src=\"\/wp-content\/uploads\/2019\/04\/091725fc108d6ce1a5fc9ae866e2c395.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kuna messaging on t\u00e4ielikult as\u00fcnkroonne, jaguneb kliendi vahetus kaheks faasiks:<\/p>\n<p><\/p>\n<ol>\n<li>\n<p>P\u00e4ringu saatmine<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">messaging:request(Exchange, ResponseMatchingTag, RequestDefinition, HandlerProcess).<\/code><\/pre>\n<p><\/p>\n<p><em>Exchange<\/em> \u2012 unikaalne vahetuspunkti nimi<br \/>\n<em>ResponseMatchingTag<\/em> \u2012 kohalik silt vastuse t\u00f6\u00f6tlemiseks. N\u00e4iteks, kui saadetakse mitu sama taotlust erinevatelt kasutajatelt.<br \/>\n<em>RequestDefinition<\/em> \u2012 taotluse keha<br \/>\n<em>HandlerProcess<\/em> \u2012 t\u00f6\u00f6tleja PID. See protsess saab serverilt vastuse.<\/p>\n<p>\n<\/li>\n<li>\n<p>Vastuse t\u00f6\u00f6tlemine<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">handle_info(#'$msg'{exchange = EXCHANGE, tag = ResponseMatchingTag,message = ResponsePayload}, State)<\/code><\/pre>\n<p><\/p>\n<p><em>ResponsePayload<\/em> \u2012 serveri vastus.<\/p>\n<p>\n<\/li>\n<\/ol>\n<p><\/p>\n<p>Serveri protsess koosneb ka kahest faasist:<\/p>\n<p><\/p>\n<ol>\n<li>Vahetuspunkti initsialiseerimine<\/li>\n<li>Saadetud taotluste t\u00f6\u00f6tlemine<\/li>\n<\/ol>\n<p><\/p>\n<p>Ilustreerime seda n\u00e4idet koodiga. Oletame, et peame rakendama lihtsat teenust, mis pakkub ainukest t\u00e4pset aja meetodit.<\/p>\n<p><\/p>\n<h4 id=\"kod-servera\">Serveri kood<\/h4>\n<p><\/p>\n<p>Viime teenuse API m\u00e4\u00e4ratlemise api.hrl faili:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">%% =====================================================\n%%  entities\n%% =====================================================\n-record(time, {\n  unixtime :: non_neg_integer(),\n  datetime :: binary()\n}).\n\n-record(time_error, {\n  code :: non_neg_integer(),\n  error :: term()\n}).\n\n%% =====================================================\n%%  methods\n%% =====================================================\n-record(time_req, {\n  opts :: term()\n}).\n-record(time_resp, {\n  result :: #time{} | #time_error{}\n}).<\/code><\/pre>\n<p><\/p>\n<p>M\u00e4\u00e4ratleme teenuse kontrolleri time_controller.erl<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">%% N\u00e4ites on n\u00e4idatud vaid oluline kood. Selle lisamine gen_server mallile annab t\u00f6\u00f6tava teenuse.\n\n%% gen_serveri initsialiseerimine\ninit(Args) -&gt;\n  %% \u00fchendamine vahetuspunktiga\n  messaging:monitor_exchange(req_resp, ?EXCHANGE, default, self())\n  {ok, #{}}.\n\n%% kontakt kaotamise s\u00fcndmuse t\u00f6\u00f6tlemine vahetuspunktiga. Sama s\u00fcndmus esitatakse, kui vahetuspunkt pole veel k\u00e4ivitatud.\nhandle_info(#exchange_die{exchange = ?EXCHANGE}, State) -&gt;\n  erlang:send(self(), monitor_exchange),\n  {noreply, State};\n\n%% API t\u00f6\u00f6tlemine\nhandle_info(#time_req{opts = _Opts}, State) -&gt;\n  messaging:response_once(Client, #time_resp{\nresult = #time{ unixtime = time_utils:unixtime(now()), datetime = time_utils:iso8601_fmt(now())}\n  });\n  {noreply, State};\n\n%% gen_serveri l\u00f5petamine\nterminate(_Reason, _State) -&gt;\n  messaging:demonitor_exchange(req_resp, ?EXCHANGE, default, self()),\n  ok.<\/code><\/pre>\n<p><\/p>\n<h4 id=\"kod-klienta\">Kliendi kood<\/h4>\n<p><\/p>\n<p>Kliendis teenusele p\u00e4ringu saatmiseks saab igal pool kutsuda messaging request API-d:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">case messaging:request(?EXCHANGE, tag, #time_req{opts = #{}}, self()) of\n    ok -&gt; ok;\n    _ -&gt; %% kordamise v\u00f5i eba\u00f5nnestumise loogika\nend<\/code><\/pre>\n<p><\/p>\n<p>Jaotatud s\u00fcsteemis v\u00f5ivad komponentide konfiguratsioonid olla erinevad ning p\u00e4ringu ajal ei pruugi messaging k\u00e4ivituda v\u00f5i teenuse kontroller ei pruugi p\u00e4ringut teenindamiseks valmis olla. Seet\u00f5ttu peame kontrollima messagingu vastust ja t\u00f6\u00f6tlema eba\u00f5nnestumise juhtumi.<br \/>\nP\u00e4rast eduka saatmise korral saab klient teenuselt vastuse v\u00f5i vea.<br \/>\nK\u00e4sitleme m\u00f5lemat juhtumit handle_info-s:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">handle_info(#'$msg'{exchange = ?EXCHANGE, tag = tag, message = #time_resp{result = #time{unixtime = Utime}}}, State) -&gt;\n  ?debugVal(Utime),\n  {noreply, State};\n\nhandle_info(#'$msg'{exchange = ?EXCHANGE, tag = tag, message = #time_resp{result = #time_error{code = ErrorCode}}}, State) -&gt;\n  ?debugVal({error, ErrorCode}),\n  {noreply, State};<\/code><\/pre>\n<p><\/p>\n<h3 id=\"request-chunked-response\">P\u00e4ring-osaline vastus<\/h3>\n<p><\/p>\n<p>Suurem s\u00f5numite saatmine ei ole soovitatav. See m\u00f5jutab kogu s\u00fcsteemi reageerimist ja stabiilsust. Kui vastus p\u00e4ringule v\u00f5tab palju m\u00e4lu, on jagamine osadeks h\u00e4davajalik.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokkide. Esimene l\u00e4henemine\" src=\"\/wp-content\/uploads\/2019\/04\/bd60742a933a8e4e3eeaf7f4adf00f2a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tooksin paar sellist juhtumit:<\/p>\n<p><\/p>\n<ul>\n<li>Komponendid vahetavad binaarandmeid, n\u00e4iteks faile. Vastuse jagamine v\u00e4ikesteks osadeks aitab t\u00f5husalt t\u00f6\u00f6tada mis tahes suurusega failidega ning v\u00e4ltida m\u00e4lu \u00fclevoolu.<\/li>\n<li>Loendid. N\u00e4iteks peame valima k\u00f5ik kirjed tohutust andmebaasi tabelist ja saatma need teisele komponendile.<\/li>\n<\/ul>\n<p><\/p>\n<p>Ma kutsun selliseid vastuseid veduriteks. Igatahes on 1024 s\u00f5numit, iga\u00fches 1 MB, parem kui \u00fcksainus s\u00f5num, mille suurus on 1 GB. <\/p>\n<p><\/p>\n<p>Erlangi klastris saame t\u00e4iendava eelise \u2013 koormuse v\u00e4hendamine vahetuspunktile ja v\u00f5rgu koormusele, kuna vastused suunatakse otse saajale, m\u00f6\u00f6da vahetuspunkti.<\/p>\n<p><\/p>\n<h3 id=\"response-with-request\">Vastus p\u00e4ringu alusel<\/h3>\n<p><\/p>\n<p>See on \u00fcsna haruldane RPC-mudeli modifikatsioon dialoogis\u00fcsteemide loomisel.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokkide. Esimene l\u00e4henemine\" src=\"\/wp-content\/uploads\/2019\/04\/9b350a0b48ca8acdca973da2f7eadb76.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<h3 id=\"publish-subscribe-data-distribution-tree\">Publish-subscribe (andmete jaotamise puu)<\/h3>\n<p><\/p>\n<p>S\u00fcndmustep\u00f5hised s\u00fcsteemid toimetavad andmed tarbijatele kohe, kui need on valmis. Nii kalduvad s\u00fcsteemid pigem push-mudelile kui pull v\u00f5i poll. See omadus v\u00f5imaldab mitte raisata ressursse, pidevalt k\u00fcsides ja oodates andmeid.<br \/>\nJoonisel on kujutatud s\u00f5numi edastamise protsessi tarbijatele, kes on registreeritud konkreetse teema jaoks.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokkide. Esimene l\u00e4henemine\" src=\"\/wp-content\/uploads\/2019\/04\/e211d5dcfeb5ce8513699eac8e3b6d84.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Klassikalised n\u00e4ited selle mustri kasutamisest on oleku levitamine: m\u00e4ngumaailma arvutim\u00e4ngudes, turuandmed b\u00f6rsil, kasulik informatsioon andmevoogudes.<\/p>\n<p><\/p>\n<p>Vaatame tellija koodi:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">init(_Args) -&gt;\n  %% registreerume vahetuspunktis, v\u00f5ti = key\n  messaging:subscribe(?SUBSCRIPTION, key, tag, self()),\n  {ok, #{}}.\n\nhandle_info(#exchange_die{exchange = ?SUBSCRIPTION}, State) -&gt;\n  %% kui vahetuspunkt pole saadaval, proovime uuesti \u00fchenduda\n  messaging:subscribe(?SUBSCRIPTION, key, tag, self()),\n  {noreply, State};\n\n%% t\u00f6\u00f6tleme saabunud s\u00f5numeid\nhandle_info(#'$msg'{exchange = ?SUBSCRIPTION, message = Msg}, State) -&gt;\n  ?debugVal(Msg),\n  {noreply, State};\n\n%% tarbija peatamisel katkestame \u00fchenduse vahetuspunktiga\nterminate(_Reason, _State) -&gt;\n  messaging:unsubscribe(?SUBSCRIPTION, key, tag, self()),\n  ok.<\/code><\/pre>\n<p><\/p>\n<p>Allikas v\u00f5ib kutsuda esile s\u00f5numi avaldamise mis tahes soovitud kohas:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">messaging:publish_message(Exchange, Key, Message).<\/code><\/pre>\n<p><\/p>\n<p><em>Exchange<\/em> \u2012 vahetuspunkti nimi,<br \/>\n<em>Ava<\/em> \u2012 marsruudi v\u00f5ti,<br \/>\n<em>S\u00f5num,<\/em> \u2012 koormus,<\/p>\n<p><\/p>\n<h2 id=\"inverted-publish-subscribe\">P\u00f6\u00f6rdprotsesside \u00fclekandmine<\/h2>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokkide. Esimene l\u00e4henemine\" src=\"\/wp-content\/uploads\/2019\/04\/2ef7cd7de459455937bdcfa8a11fd028.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pub-sub\u2018i juurutamine v\u00f5imaldab saada logimisele mugava mustri. Allikate ja tarbimise komplekt v\u00f5ib olla t\u00e4iesti erinev. Joonisel on kujutatud olukorda, kus on \u00fcks tarbija ja palju allikaid.<\/p>\n<p><\/p>\n<h2 id=\"task-distribution-pattern\">\u00dclesannete jaotamise muster.<\/h2>\n<p><\/p>\n<p>Pealmost igas projektis tekivad viivitusega t\u00f6\u00f6tlemise \u00fclesanded, nagu aruannete koostamine, teavituste saatmine, andmete saamine v\u00e4liste s\u00fcsteemide kaudu. Nende \u00fclesannete t\u00e4itmise s\u00fcsteemi l\u00e4bilaskev\u00f5imet saab h\u00f5lpsasti skaleerida, lisades t\u00f6\u00f6tlejat. Meie \u00fclesanne on moodustada t\u00f6\u00f6tlejate klaster ja jaotada \u00fclesanded nende vahel v\u00f5rdselt.<\/p>\n<p><\/p>\n<p>Vaatleme tekkinud olukordi kolme t\u00f6\u00f6tleja n\u00e4itel. Juba \u00fclesannete jagamise etapis t\u00f5useb esile \u00f5igusem\u00f5istmise k\u00fcsimus ja t\u00f6\u00f6tlejate \u00fclevoolu v\u00e4ltimine. \u00d5igusem\u00f5istmise eest vastutab round-robin jaotamine ning et v\u00e4ltida t\u00f6\u00f6tlejate \u00fclevoolu, seame piirangu <em>prefetch_limit<\/em>. \u00dcleminekuperioodides <em>prefetch_limit<\/em> ei luba \u00fchelgi t\u00f6\u00f6tlejal saada k\u00f5iki \u00fclesandeid.<\/p>\n<p><\/p>\n<p>Messsage haldab j\u00e4rjekordi ja t\u00f6\u00f6tlemise prioriteete. T\u00f6\u00f6tlejad saavad \u00fclesandeid nende saabumise j\u00e4rjekorras. \u00dclesande t\u00e4itmine v\u00f5ib l\u00f5ppeda kas edukalt v\u00f5i eba\u00f5nnestumisega:<\/p>\n<p><\/p>\n<ul>\n<li><code>messaging:ack(Tack)<\/code> \u2012 kutsutakse esile s\u00f5numi eduka t\u00f6\u00f6tlemise korral.<\/li>\n<li><code>messaging:nack(Tack)<\/code> \u2012 kutsutakse esile igasugustes erakorralistes olukordades. P\u00e4rast \u00fclesande tagastamist edastab s\u00f5numiteenus selle teisele t\u00f6\u00f6tlejale.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokkide. Esimene l\u00e4henemine\" src=\"\/wp-content\/uploads\/2019\/04\/c2c632b6411247ee8b0dcfb3250a4503.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Olgu \u00f6eldud, et kolme \u00fclesande t\u00f6\u00f6tlemisel toimus keeruline eba\u00f5nnestumine: t\u00f6\u00f6tleja 1 kukkus p\u00e4rast \u00fclesande saamist kokku, ilma et oleks j\u00f5udnud vahetuspunktile midagi teatada. Sellisel juhul edastab vahetuspunkt \u00fclesande p\u00e4rast ack timeout'i m\u00f6\u00f6dumist teisele t\u00f6\u00f6tlejale. T\u00f6\u00f6tleja 3 keeldus mingil p\u00f5hjusel \u00fclesandest ja saatis nack'i, l\u00f5puks l\u00e4ks \u00fclesanne ka teisele t\u00f6\u00f6tlejale, kes selle edukalt t\u00e4itis.<\/p>\n<p><\/p>\n<h2 id=\"predvaritelnyy-itog\">Eelkokkuv\u00f5te<\/h2>\n<p><\/p>\n<p>Oleme k\u00e4sitlenud jaotatud s\u00fcsteemide p\u00f5hikivisid ning omandanud nende rakendamise p\u00f5hiteadmisi Erlangis\/Elixir'is.<\/p>\n<p><\/p>\n<p>Kombineerides p\u00f5himustreid, on v\u00f5imalik luua keerulisi paradigmadesse probleemide lahendamiseks.<\/p>\n<p><\/p>\n<p>Selle ts\u00fckli l\u00f5pposas k\u00e4sitleme teenuste korraldust, marsruutimist ja koormuse tasakaalustamist, samuti r\u00e4\u00e4gime s\u00fcsteemide skaleeritavuse ja talitluspidevuse praktilisest k\u00fcljest.<\/p>\n<p><\/p>\n<p>Teise osa l\u00f5pp.<\/p>\n<p><\/p>\n<p>Foto <noindex>Marius Christensen<\/noindex><br \/>\nIllustratsioonid on koostatud websequencediagrams.com abil.<\/p>\n<p>Allikas: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446108\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438 \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043e\u0441\u043d\u043e\u0432\u044b \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b. \u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e \u043f\u043e\u0442\u043e\u043a\u0430\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u0443\u0442\u044f\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 Erlang\/Elixir \u0441\u0438\u0441\u0442\u0435\u043c \u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u0445 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u0432 \u043d\u0438\u0445: Request-response Request-Chunked Response Response with Request Publish-subscribe Inverted Publish-subscribe Task distribution SOA, MSA \u0438 \u043e\u0431\u043c\u0435\u043d \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 SOA, MSA \u2013 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0449\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0441\u0438\u0441\u0442\u0435\u043c, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":22886,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-30908","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.1.1 - aioseo.com -->\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\/et\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"et_EE\" \/>\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. \u041f\u0435\u0440\u0432\u043e\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-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:38:07+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:38:07+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\udd47Jaotatud rakenduste ehitusplokid. Esimene l\u00e4henemine | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"et_EE","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. \u041f\u0435\u0440\u0432\u043e\u0435 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0435\u043d\u0438\u0435 | ProHoster","og:url":"https:\/\/prohoster.info\/et\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-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:38:07+00:00","article:modified_time":"2019-10-31T18:38:07+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"30908","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-02-22 15:33:36","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 03:27:06","updated":"2026-02-22 15:33:36","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/30908","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/comments?post=30908"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/30908\/revisions"}],"predecessor-version":[{"id":162009,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/posts\/30908\/revisions\/162009"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media\/22886"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/media?parent=30908"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/categories?post=30908"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/et\/wp-json\/wp\/v2\/tags?post=30908"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}