{"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 ehitusplokid. Esimene l\u00e4henemine.","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokid. Esimene l\u00e4henemine.\" src=\"\/wp-content\/uploads\/2019\/04\/7ef485e452075775ce317b557671274c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Eelmises osas <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446028\/\">artiklis<\/a><\/noindex> oleme k\u00e4sitlenud reaktiivse arhitektuuri teoreetilisi aluseid. On aeg r\u00e4\u00e4kida andmevoogudest, reaktiivsete Erlang\/Elixir s\u00fcsteemide rakenduste teedest ja s\u00f5numivahetuse mustritest neis:<\/p>\n<p><\/p>\n<ul>\n<li>P\u00e4ring-vastus<\/li>\n<li>P\u00e4ring-Chunked vastus<\/li>\n<li>Vastus koos p\u00e4ringuga<\/li>\n<li>Avalda-tellimine<\/li>\n<li>P\u00f6\u00f6ratud avalda-tellimine<\/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, MSA on s\u00fcsteemi arhitektuurid, mis m\u00e4\u00e4ratlevad s\u00fcsteemide loomise reeglid, samas kui s\u00f5numivahetus pakub selle rakendamiseks primitiive.<\/p>\n<p><\/p>\n<p>Ma ei soovi propageerida \u00fchtegi teatud s\u00fcsteemide arhitektuuri. Olen selle poolt, et rakendada konkreetse projekti ja \u00e4ri jaoks v\u00f5imalikult t\u00f5husaid ja kasulikku praktikat. \u00dcksk\u00f5ik, millise paradigma me valime, on s\u00fcsteemide plokkide loomine parem Unix-viisi kohaselt: minimaalsete seotud komponentidega, mis vastutavad eraldi \u00fcksuste eest. API meetodid t\u00e4idavad v\u00f5imalikult lihtsaid toiminguid \u00fcksustega.<\/p>\n<p><\/p>\n<p>Messaging \u2012 nagu nimigi viitab \u2012 on s\u00f5numivahetusplatvorm. Selle peamine eesm\u00e4rk on s\u00f5numite vastuv\u00f5tmine ja edastamine. See vastutab teabe edastamise liideste, loogiliste teabe\u00fclekande kanalite loomise, marsruutimise ja koormuse tasakaalustamise ning s\u00fcsteemi tasandil rikke t\u00f6\u00f6tlemise eest.<br \/>\nKavandatav messaging ei p\u00fc\u00fca konkureerida rabbitmq v\u00f5i asendada seda. Selle p\u00f5hijooned on:<\/p>\n<p><\/p>\n<ul>\n<li>Jaotatus.<br \/>\nVahetuspunktide loomine on v\u00f5imalik klastrite k\u00f5igil s\u00f5lmedel, maksimaalselt l\u00e4hedal koodile, mis neid kasutab.<\/li>\n<li>Lihtsus.<br \/>\nSuunatus \u0448\u0430\u0431\u043b\u043e\u043d\u043d koodi v\u00e4hendamisele ja kasutusmugavusele.<\/li>\n<li>Parim j\u00f5udlus.<br \/>\nMe ei p\u00fc\u00fca reprodutseerida rabbitmq funktsionaalsust, vaid eristame ainult arhitektuuri ja transportkihi, mida integreerime v\u00f5imalikult lihtsalt OTP-sse, minimeerides kulusid.<\/li>\n<li>Paindlikkus.<br \/>\nIga teenus v\u00f5ib sisaldada mitmeid vahetusmalle.<\/li>\n<li>Veakindlus, mis on sisse ehitatud disaini.<\/li>\n<li>Skaalautuvus.<br \/>\nMessaging kasvab koos rakendusega. Koormuse suurenedes saab vahetuspunktid viia eraldi masinatesse.<\/li>\n<\/ul>\n<p><\/p>\n<p><em>M\u00e4rkus.<\/em> Koodiorganisatsiooni vaatenurgast sobivad keerukate s\u00fcsteemide jaoks Erlangi\/Elixiri meta-projektid h\u00e4sti. Kogu projekti kood asub \u00fches hoidlas \u2012 katuseprojekti all. Samal ajal on mikroteenused maksimaalselt isoleeritud ja teevad lihtsaid operatsioone, mis vastutavad eraldi entiteedi eest. Sel viisil on s\u00fcsteemi API-d lihtne hallata, muudatusi h\u00f5lbus teha ning mugav on kirjutada \u00fcksus- ja integratsiooniteste.<\/p>\n<p><\/p>\n<p>S\u00fcsteemi komponendid suhtlevad otse v\u00f5i kaudu vahendaja. Messaging'u seisukohalt on igal teenusel mitu eluts\u00fckli faasi:<\/p>\n<p><\/p>\n<ul>\n<li>Teenuse initsialiseerimine.<br \/>\nSellel etapil toimub teenuse t\u00e4itmise protsessi 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 luua vahetuspunktid d\u00fcnaamiliselt. <\/li>\n<li>Teenuse registreerimine.<br \/>\nKuna teenus peab sooritama p\u00e4ringud, tuleb see registreerida vahetuspunktis.<\/li>\n<li>Normaalne t\u00f6\u00f6.<br \/>\nTeenuse teostab kasulikku t\u00f6\u00f6d.<\/li>\n<li>T\u00f6\u00f6 l\u00f5petamine.<br \/>\nOn v\u00f5imalikud kaks t\u00f6\u00f6 l\u00f5petamise viisi: regulaarne ja h\u00e4daolukord. Regulaarse l\u00f5petamise korral katkestatakse teenus vahetuspunktiga ja peatutakse. H\u00e4daolukordade puhul k\u00e4ivitab messaging \u00fche rikke t\u00f6\u00f6tlemise stsenaariumi.<\/li>\n<\/ul>\n<p><\/p>\n<p>See n\u00e4eb v\u00e4lja \u00fcsna keeruline, kuid koodis pole k\u00f5ik nii hull. Koodin\u00e4ited koos kommentaaridega esitatakse natuke hiljem mallide anal\u00fc\u00fcsis.<\/p>\n<p><\/p>\n<h2 id=\"exchanges\">Vahetused<\/h2>\n<p><\/p>\n<p>Vahetuspunkt on messaging protsess, mis rakendab loogikat komponentide vahel suhtlemiseks vahetusskeemis. K\u00f5ik alltoodud n\u00e4idised suhtlevad l\u00e4bi vahetuspunktide, mille kombinatsioon moodustab messaging'i.<\/p>\n<p><\/p>\n<h2 id=\"message-exchange-patterns-meps\">Message exchange patterns (MEPs)<\/h2>\n<p><\/p>\n<p>Globaalsetel mallidel saab jagada kahepoolseteks ja \u00fchepoolseteks. Esimeseid iseloomustab vastus saadud s\u00f5numile, teised mitte. Kliendiserveri arhitektuuri klassikaline n\u00e4ide kahepoolsetest mallidest on Request-response mall. Vaatleme mallide ja nende modifikatsioonide n\u00e4it.<\/p>\n<p><\/p>\n<h3 id=\"requestresponse-ili-rpc\">Request\u2013response ehk RPC<\/h3>\n<p><\/p>\n<p>RPC-d kasutatakse, kui meil on vaja saada vastus teiselt protsessilt. See protsess v\u00f5ib k\u00e4ivituda samas s\u00f5lmes v\u00f5i asuda teisel kontinendil. Allpool on toodud kliendi ja <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/et\/server\/dts-los-angeles\/\"   title=\"serverile\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"3483\">serverile<\/a> messaging kaudu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokid. 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>Vahetus<\/em> \u2012 vahetuse unikaalne nimi<br \/>\n<em>ResponseMatchingTag<\/em> \u2012 lokaalne silt vastuse t\u00f6\u00f6tlemiseks. N\u00e4iteks, kui saadetakse mitu sama p\u00e4ringut erinevatelt kasutajatelt.<br \/>\n<em>RequestDefinition<\/em> \u2012 p\u00e4ringu keha<br \/>\n<em>HandlerProcess<\/em> \u2012 t\u00f6\u00f6tleja PID. Sellele protsessile saadetakse serverilt vastus.<\/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 jaoks koosneb protsess samuti kahest faasist:<\/p>\n<p><\/p>\n<ol>\n<li>Vahetuspunkti initsialiseerimine<\/li>\n<li>Saabuvate p\u00e4ringute t\u00f6\u00f6tlemine<\/li>\n<\/ol>\n<p><\/p>\n<p>Illustreerime seda mallikoodiga. Oletame, et peame rakendama lihtsat teenust, mis pakub t\u00e4pset aega.<\/p>\n<p><\/p>\n<h4 id=\"kod-servera\">Serveri kood<\/h4>\n<p><\/p>\n<p>V\u00f5tame teenuse API m\u00e4\u00e4ratlemise api.hrl:<\/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\u00e4rame teenuse kontrolleri time_controller.erl<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">%% N\u00e4ites on esitatud ainult oluline kood. Lisades selle gen_server mallile, saab t\u00f6\u00f6tava teenuse.\n\n%% gen_serveri algatamine\ninit(Args) -&gt;\n  %% \u00fchendamine vahetuspunktiga\n  messaging:monitor_exchange(req_resp, ?EXCHANGE, default, self())\n  {ok, #{}}.\n\n%% vahetuspunktiga \u00fchenduse katkemise s\u00fcndmuse t\u00f6\u00f6tlemine. See s\u00fcndmus tuleb ka siis, kui vahetuspunkti ei ole veel alustatud.\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>Et saata p\u00e4ring teenusele, v\u00f5ib kliendi igas kohas kutsuda esile messaging request API:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">juhtum messaging:request(?EXCHANGE, tag, #time_req{opts = #{}}, self()) of\n    ok -&gt; ok;\n    _ -&gt; %% kordus v\u00f5i eba\u00f5nnestumise loogika\nl\u00f5pp<\/code><\/pre>\n<p><\/p>\n<p>Jaotatud s\u00fcsteemis v\u00f5ivad komponentide konfiguratsioonid olla v\u00e4ga erinevad ning messaging'i p\u00e4ringu hetkeks v\u00f5ib see veel mitte k\u00e4ivituda, v\u00f5i teenuse kontroller ei pruugi p\u00e4ringut teenindamiseks valmis olla. Seet\u00f5ttu on meil vajalik kontrollida messaging'i vastust ja t\u00f6\u00f6delda eba\u00f5nnestumise juhtumit.<br \/>\nP\u00e4rast edukat saatmist saadab teenus kliendile vastuse v\u00f5i vea.<br \/>\nT\u00f6\u00f6tleme m\u00f5lemat juhtumit funktsioonis handle_info:<\/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-Chunked vastus<\/h3>\n<p><\/p>\n<p>Parim on v\u00e4ltida suurte s\u00f5numite edastamist. See m\u00f5jutab kogu s\u00fcsteemi reageerimisv\u00f5imet ja stabiilsust. Kui p\u00e4ringu vastus v\u00f5tab palju m\u00e4lu, on jagamine osadeks kohustuslik.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokid. Esimene l\u00e4henemine.\" src=\"\/wp-content\/uploads\/2019\/04\/bd60742a933a8e4e3eeaf7f4adf00f2a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Tuletan meelde paar sellise juhtumi n\u00e4idet:<\/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 igasuguste suurustega failidega ja v\u00e4ltida m\u00e4luh\u00e4ireid.<\/li>\n<li>Loendid. N\u00e4iteks peame valima k\u00f5ik kirjed suurst andmebaasi tabelist ja edastama need teisele komponendile.<\/li>\n<\/ul>\n<p><\/p>\n<p>Ma nimetan selliseid vastuseid rongiks. \u00dcksk\u00f5ik kuidas, 1024 s\u00f5numit, iga\u00fche maht 1 MB, on parem kui \u00fcksainus s\u00f5num, mille maht on 1 GB. <\/p>\n<p><\/p>\n<p>Erlang klastris saavutame t\u00e4iendava eelise - koormuse v\u00e4henemise vahetuspunktis ja v\u00f5rgus, kuna vastused suunatakse kohe saajale, m\u00f6\u00f6da vahetuspunkti.<\/p>\n<p><\/p>\n<h3 id=\"response-with-request\">Vastus koos p\u00e4ringuga<\/h3>\n<p><\/p>\n<p>See on \u00fcsna harv RPC mustri modifikatsioon, mida kasutatakse dialoogis\u00fcsteemide loomisel.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokid. 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 (andmejaotuse puu)<\/h3>\n<p><\/p>\n<p>S\u00fcndmuste poolt suunatud s\u00fcsteemid edastavad andmed tarbijatele, kui need on valmis. Seet\u00f5ttu kalduvad s\u00fcsteemid pigem push-mudelile kui pull- v\u00f5i poll-mudelile. See omadus v\u00f5imaldab mitte raisata ressursse, k\u00fcsides pidevalt ja oodates andmeid.<br \/>\nJoonisel on kujutatud s\u00f5numi levitamise protsess tarbijatele, kes on registreeritud teatud teema jaoks.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokid. 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 videom\u00e4ngudes, turuandmed b\u00f6rsidel, kasulik info andmevoogudes.<\/p>\n<p><\/p>\n<p>Vaatame tellija koodi:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">init(_Args) -&gt;\n  %% liitume vahetusse, v\u00f5ti = key\n  messaging:subscribe(?SUBSCRIPTION, key, tag, self()),\n  {ok, #{}}.\n\nhandle_info(#exchange_die{exchange = ?SUBSCRIPTION}, State) -&gt;\n  %% kui vahetuspunkt ei ole saadaval, proovime uuesti \u00fchendust luua\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 lahkume vahetuspunktist\nterminate(_Reason, _State) -&gt;\n  messaging:unsubscribe(?SUBSCRIPTION, key, tag, self()),\n  ok.<\/code><\/pre>\n<p><\/p>\n<p>Allikas v\u00f5ib kutsuda s\u00f5numi avaldamise funktsiooni mistahes sobivas kohas:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">messaging:publish_message(Exchange, Key, Message).<\/code><\/pre>\n<p><\/p>\n<p><em>Vahetus<\/em> \u2012 vahetuspunkti nimi,<br \/>\n<em>Ava\u00f5igus<\/em> \u2012 suunamisv\u00f5ti<br \/>\n<em>S\u00f5num<\/em> \u2012 koormus<\/p>\n<p><\/p>\n<h2 id=\"inverted-publish-subscribe\">P\u00f6\u00f6ratud avalda-tellimine<\/h2>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Jaotatud rakenduste ehitusplokid. 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'i rakendamisega saab luua mustri, mis sobib logimiseks. Allikate ja tarbijate komplekt v\u00f5ib olla t\u00e4iesti erinev. Joonisel on kujutatud juhtumit, kus on \u00fcks tarbija ja mitu allikat.<\/p>\n<p><\/p>\n<h2 id=\"task-distribution-pattern\">\u00dclesannete jaotamise mustr<\/h2>\n<p><\/p>\n<p>Peaaegu igas projektis tekivad viivitustega t\u00f6\u00f6tlemise \u00fclesanded, nagu aruannete koostamine, teadete saatmine ja andmete hankimine kolmandate osapoolte s\u00fcsteemidest. S\u00fcsteemi l\u00e4bilaskev\u00f5imet, mis neid \u00fclesandeid t\u00e4idab, on kerge skaleerida, lisades t\u00f6\u00f6tlejad. K\u00f5ik, mis me peame tegema, on luua t\u00f6\u00f6tlejate klaster ja jaotada \u00fclesanded nende vahel \u00fchtlaselt.<\/p>\n<p><\/p>\n<p>Vaatame esilekerkivaid olukordi 3 t\u00f6\u00f6tleja n\u00e4itel. Veel enne \u00fclesannete jaotamist t\u00f5useb \u00f5iglasuse ja \u00fclekoormuse k\u00fcsimus. \u00d5iglasuse eest vastutab ringjaotus, ja et v\u00e4ltida t\u00f6\u00f6tlejate \u00fclekoormust, kehtestame piiri <em>prefetch_limit<\/em>. \u00dcleminekure\u017eiimides <em>prefetch_limit<\/em> ei lase \u00fchel t\u00f6\u00f6tlejal k\u00f5iki \u00fclesandeid saada.<\/p>\n<p><\/p>\n<p>S\u00f5numihaldus haldab j\u00e4rjekordi ja t\u00f6\u00f6tlemise prioriteeti. T\u00f6\u00f6tlejad saavad \u00fclesandeid vastavalt nende saabumisele. \u00dclesande t\u00e4itmine v\u00f5ib l\u00f5ppeda kas edukalt v\u00f5i l\u00e4bikukkumisega:<\/p>\n<p><\/p>\n<ul>\n<li><code>messaging:ack(Tack)<\/code> \u2012 kutsutakse \u00fclesande eduka t\u00f6\u00f6tlemise korral<\/li>\n<li><code>messaging:nack(Tack)<\/code> \u2012 kutsutakse esile k\u00f5igis ebatavalistes 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 ehitusplokid. Esimene l\u00e4henemine.\" src=\"\/wp-content\/uploads\/2019\/04\/c2c632b6411247ee8b0dcfb3250a4503.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Oletame, et kolme \u00fclesande t\u00f6\u00f6tlemise k\u00e4igus tekkis keeruline rike: t\u00f6\u00f6tleja 1 kukkus \u00fclesande saamisel kokku, ilma et oleks vahetusele midagi edastanud. Sellisel juhul edastab vahetus p\u00e4rast ack timeout'i l\u00f5ppu \u00fclesande teisele t\u00f6\u00f6tlejale. T\u00f6\u00f6tleja 3 loobus mingil p\u00f5hjusel \u00fclesandest ja saatis nack, seet\u00f5ttu l\u00e4ks \u00fclesanne ka teisele t\u00f6\u00f6tlejale, kes selle edukalt t\u00e4itis.<\/p>\n<p><\/p>\n<h2 id=\"predvaritelnyy-itog\">Esialgne kokkuv\u00f5te<\/h2>\n<p><\/p>\n<p>Oleme kaasanud ja p\u00f5hjalikult arutanud jaotatud s\u00fcsteemide p\u00f5hielemente ja saanud nende rakendamise kohta algteadmised Erlangis\/Elixir'is.<\/p>\n<p><\/p>\n<p>Kombineerides p\u00f5hivorme, on v\u00f5imalik luua keerulisi paradigmasid, et lahendada esilekerkivaid probleeme.<\/p>\n<p><\/p>\n<p>Ts\u00fckli l\u00f5pus vaatame \u00fcldisi teenuste korraldamise, marsruutimise ja tasakaalustamise k\u00fcsimusi ning arutame ka praktilisi k\u00fclgi s\u00fcsteemide skaleeritavuse ja talitlush\u00e4irete vastupidavuse osas.<\/p>\n<p><\/p>\n<p>Ts\u00fckli teine osa on l\u00f5ppenud.<\/p>\n<p><\/p>\n<p>Foto <noindex>Marius Christensen<\/noindex><br \/>\nIllustratsioonid on valmistatud 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.0.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\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\" \/>\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.0.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:description\" content=\"\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\" \/>\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":"Eelmises artiklis k\u00e4sitlesime reaktiivse arhitektuuri teoreetilisi aluseid. On aeg r\u00e4\u00e4kida andmevoogudest, reaktiivsete Erlangi\/Elixiri s\u00fcsteemide rakendamisviisidest ja nende s\u00f5numivahetuse mustritest: p\u00e4ring-vastus, p\u00e4ring-t\u00fckeldatud vastus, vastus koos p\u00e4ringuga, avalik-privaatne, p\u00f6\u00f6ratud avalik-privaatne, \u00fclesannete jaotamine. SOA, MSA ja s\u00f5numivahetus. SOA ja MSA on s\u00fcsteemi arhitektuurid, mis m\u00e4\u00e4ratlevad s\u00fcsteemide loomise reeglid, samal ajal kui","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:description":"\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","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}]}}