{"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\/sl\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie","title":{"rendered":"Gradniki porazdeljenih aplikacij. Prvo pribli\u017eno","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Gradniki porazdeljenih aplikacij. Prvo pribli\u017eno\" src=\"\/wp-content\/uploads\/2019\/04\/7ef485e452075775ce317b557671274c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>V prej\u0161njem <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446028\/\">\u010dlanku<\/a><\/noindex> razpravljali smo o teoreti\u010dnih temeljih reaktivne arhitekture. \u010cas je, da govorimo o tokovih podatkov, na\u010dinih izvajanja reaktivnih sistemov Erlang\/Elixir in vzorcih izmenjave sporo\u010dil v njih:<\/p>\n<p><\/p>\n<ul>\n<li>Zahteva-odziv<\/li>\n<li>Zahteva-razdeljen odziv<\/li>\n<li>Odziv z zahtevo<\/li>\n<li>Objavi-naro\u010di<\/li>\n<li>Inverzno objavi-naro\u010di<\/li>\n<li>Porazdelitev nalog<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"soa-msa-i-obmen-soobscheniyami\">SOA, MSA in izmenjava sporo\u010dil<\/h2>\n<p><\/p>\n<p>SOA, MSA \u2013 sistemske arhitekture, ki dolo\u010dajo pravila za zgradnjo sistemov, medtem ko izmenjava sporo\u010dil zagotavlja primitivne funkcije za njihovo izvajanje.<\/p>\n<p><\/p>\n<p>Ne \u017eelim propagirati nobene posebej arhitekture za gradnjo sistemov. Pristojno za uporabo kar najbolj u\u010dinkovitih in koristnih praks za dolo\u010den projekt in podjetje. Katero koli paradigmo izberemo, je bolj\u0161e ustvariti sistemske bloke ob upo\u0161tevanju Unix-way: komponente z minimalno povezljivostjo, ki odgovarjajo za posamezne entitete. Metode API izvajajo \u010dim bolj preproste akcije z entitetami.<\/p>\n<p><\/p>\n<p>Izmenjava sporo\u010dil \u2013 kot je razvidno iz imena \u2013 je posrednik sporo\u010dil. Njegov glavni cilj je sprejemati in po\u0161iljati sporo\u010dila. Odgovoren je za vmesnike za po\u0161iljanje informacij, oblikovanje logi\u010dnih kanalov prenosa informacij znotraj sistema, usmerjanje in uravnote\u017eenje, ter obvladovanje odpovedi na sistemski ravni.<br \/>\nRazvijajo\u010da izmenjava sporo\u010dil ne posku\u0161a konkurirati rabbitmq ali ga zamenjati. Njene glavne zna\u010dilnosti so:<\/p>\n<p><\/p>\n<ul>\n<li>Porazdeljenost.<br \/>\nTo\u010dke izmenjave lahko ustvarimo na vseh vozli\u0161\u010dih v gru\u010di, \u010dim bli\u017eje kodi, ki jih uporablja.<\/li>\n<li>Enostavnost.<br \/>\nUsmerjenost na minimizacijo predpisanega kode in uporabni\u0161ko prijaznost.<\/li>\n<li>Najbolj\u0161a zmogljivost.<br \/>\nNe posku\u0161amo ponoviti funkcionalnosti rabbitmq, temve\u010d izpostavljamo le arhitekturno in transportno plast, ki jo \u010dim la\u017eje vklju\u010dimo v OTP, pri \u010demer minimiziramo stro\u0161ke.<\/li>\n<li>Prilagodljivost.<br \/>\nVsaka storitev lahko zdru\u017euje \u0161tevilne vzorce izmenjave.<\/li>\n<li>Odpornost na napake, vgrajena v dizajn.<\/li>\n<li>\u0160irljivost.<br \/>\nIzmenjava sporo\u010dil raste skupaj z aplikacijo. Ko se obremenitev pove\u010duje, lahko izmenjan\u010dke prenesemo na posamezne naprave.<\/li>\n<\/ul>\n<p><\/p>\n<p><em>Opomba.<\/em> Z vidika organizacije koda, za kompleksne sisteme na Erlangu\/Elixiru dobro odgovaraju meta-projekti. Sav kod projekta se nalazi u jednom repozitoriju \u2013 krovnom projektu. Pritom su mikroservisi maksimalno izolovani i obavljaju jednostavne operacije, odgovaraju\u0107i za posebnu entitet. Ovim pristupom je lako odr\u017eavati API celog sistema, jednostavno praviti izmene, a prakti\u010dno je pisati jedini\u010dne i integracione testove.<\/p>\n<p><\/p>\n<p>Komponente sistema me\u0111usobno komuniciraju direktno ili putem brokera. Sa aspekta messaging, svaka usluga ima nekoliko faza \u017eivota:<\/p>\n<p><\/p>\n<ul>\n<li>Inicijalizacija usluge.<br \/>\nU ovoj fazi se vr\u0161i konfiguracija i pokretanje izvr\u0161ne usluge i njenih zavisnosti.<\/li>\n<li>Kreiranje ta\u010dke razmene.<br \/>\nUsluga mo\u017ee koristiti stati\u010dnu ta\u010dku razmene, zadatu u konfiguraciji \u010dvora, ili stvoriti ta\u010dke razmene dinami\u010dki. <\/li>\n<li>Registracija usluge.<br \/>\nDa bi usluga mogla da obra\u0111uje zahteve, mora biti registrovana na ta\u010dki razmene.<\/li>\n<li>Normalno funkcionisanje.<br \/>\nUsluga obavlja korisni rad.<\/li>\n<li>Zavr\u0161etak rada.<br \/>\nPostoje 2 vrste zavr\u0161etka rada: redovan i vanredan. U redovnom slu\u010daju, usluga se isklju\u010duje iz ta\u010dke razmene i zaustavlja. U slu\u010daju vanrednih doga\u0111aja, messaging sprovodi jedan od scenarija obrade gre\u0161aka.<\/li>\n<\/ul>\n<p><\/p>\n<p>Izgleda prili\u010dno slo\u017eeno, ali u kodu nije sve tako stra\u0161no. Primeri koda sa komentarima bi\u0107e prikazani u analizi \u0161ablona malo kasnije.<\/p>\n<p><\/p>\n<h2 id=\"exchanges\">Exchanges<\/h2>\n<p><\/p>\n<p>Ta\u010dka razmene \u2013 proces messaging, koji realizuje logiku interakcije sa komponentama u okviru \u0161ablona razmene poruka. U svim primerima predstavljenim u nastavku, komponente komuniciraju putem ta\u010daka razmene, \u010dija kombinacija formira messaging.<\/p>\n<p><\/p>\n<h2 id=\"message-exchange-patterns-meps\">Message exchange patterns (MEPs)<\/h2>\n<p><\/p>\n<p>Globalno, \u0161ablone razmene mo\u017eemo podeliti na dvosmerne i jednosmerne. Prvi podrazumevaju odgovor na primljenu poruku, dok drugi to ne rade. Klasi\u010dan primer dvosmernog \u0161ablona u klijent-server arhitekturi je Request-response \u0161ablon. Razmotri\u0107emo \u0161ablon i njegove modifikacije.<\/p>\n<p><\/p>\n<h3 id=\"requestresponse-ili-rpc\">Request\u2013response ili RPC<\/h3>\n<p><\/p>\n<p>RPC se koristi kada nam je potreban odgovor od druge usluge. Ova usluga mo\u017ee biti pokrenuta na istom \u010dvoru ili se nalaziti na drugom kontinentu. U nastavku je prikazana shema interakcije klijenta i <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/sl\/server\/dts-los-angeles\/\"   title=\"stre\u017enika\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"3483\">stre\u017enika<\/a> putem messaging.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Gradniki porazdeljenih aplikacij. Prvo pribli\u017eno\" src=\"\/wp-content\/uploads\/2019\/04\/091725fc108d6ce1a5fc9ae866e2c395.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Po\u0161to je messaging potpuno asinkron, za klijenta se razmena deli na 2 faze:<\/p>\n<p><\/p>\n<ol>\n<li>\n<p>Slanje zahteva<\/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 unikatno ime to\u010dke razmjene<br \/>\n<em>ResponseMatchingTag<\/em> \u2012 lokalna oznaka za obradu odgovora. Na primjer, u slu\u010daju slanja vi\u0161e istih zahtjeva razli\u010ditim korisnicima.<br \/>\n<em>RequestDefinition<\/em> \u2012 tijelo zahtjeva<br \/>\n<em>HandlerProcess<\/em> \u2012 PID obraditelja. Ovaj proces \u0107e primiti odgovor od poslu\u017eitelja.<\/p>\n<p>\n<\/li>\n<li>\n<p>Obrada odgovora<\/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 odgovor poslu\u017eitelja.<\/p>\n<p>\n<\/li>\n<\/ol>\n<p><\/p>\n<p>Za poslu\u017eitelj, proces se tako\u0111er sastoji od 2 faze:<\/p>\n<p><\/p>\n<ol>\n<li>Inicijalizacija to\u010dke razmjene<\/li>\n<li>Obrada primljenih zahtjeva<\/li>\n<\/ol>\n<p><\/p>\n<p>Ilistrirajmo kodom ovu shemu. Pretpostavimo da trebamo implementirati jednostavnu uslugu koja pru\u017ea jedinu metodu ta\u010dnog vremena.<\/p>\n<p><\/p>\n<h4 id=\"kod-servera\">Kod poslu\u017eitelja<\/h4>\n<p><\/p>\n<p>Izdvojit \u0107emo definiciju API usluge u api.hrl:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">%% =====================================================\n%%  entiteti\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%%  metode\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>Definirajmo kontroler usluge u time_controller.erl<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">%% U primjeru je prikazan samo zna\u010dajan kod. Umetanjem u \u0161ablon gen_server mo\u017eete dobiti radnu uslugu.\n\n%% inicijalizacija gen_server\ninit(Args) -&gt;\n  %% povezivanje s to\u010dkom razmjene\n  messaging:monitor_exchange(req_resp, ?EXCHANGE, default, self())\n  {ok, #{}}.\n\n%% obrada doga\u0111aja gubitka veze s to\u010dkom razmjene. Ovaj doga\u0111aj dolazi i ako to\u010dka razmjene jo\u0161 nije pokrenuta.\nhandle_info(#exchange_die{exchange = ?EXCHANGE}, State) -&gt;\n  erlang:send(self(), monitor_exchange),\n  {noreply, State};\n\n%% obrada API\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%% zavr\u0161etak rada gen_server\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\">Kod klijenta<\/h4>\n<p><\/p>\n<p>Kako bismo poslali zahtjev usluzi, bilo gdje u klijentu mo\u017eemo pozvati messaging request API:<\/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; %% logika ponavljanja ili neuspjeha\nend<\/code><\/pre>\n<p><\/p>\n<p>U distribuiranom sustavu konfiguracija komponenti mo\u017ee biti vrlo razli\u010dita, te se u trenutku zahtjeva messaging mo\u017eda jo\u0161 nije pokrenuo, ili kontroler usluge ne\u0107e biti spreman obraditi zahtjev. Stoga moramo provjeriti odgovor messaging-a i obraditi slu\u010daj odbijanja.<br \/>\nNakon uspje\u0161nog slanja, klijent \u0107e primiti odgovor ili gre\u0161ku od usluge.<br \/>\nObradimo oba slu\u010daja u 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\">Zahteva-razdeljen odziv<\/h3>\n<p><\/p>\n<p>Bolje je ne dopustiti prijenos velikih poruka. To utje\u010de na odgovornost i stabilnost cijelog sustava. Ako odgovor na zahtjev zauzima previ\u0161e memorije, tada je podjela u dijelove obavezna.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Gradniki porazdeljenih aplikacij. Prvo pribli\u017eno\" src=\"\/wp-content\/uploads\/2019\/04\/bd60742a933a8e4e3eeaf7f4adf00f2a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Navedite nekoliko primjera takvih slu\u010dajeva:<\/p>\n<p><\/p>\n<ul>\n<li>Komponente razmjenjuju binarne podatke, na primjer, datoteke. Podjela odgovora u male dijelove poma\u017ee u\u010dinkovito raditi s datotekama bilo koje veli\u010dine i izbjegavati prepunjenje memorije.<\/li>\n<li>Popisi. Na primjer, trebamo odabrati sve zapise iz ogromne tablice u bazi podataka i prenijeti ih drugoj komponenti.<\/li>\n<\/ul>\n<p><\/p>\n<p>Nazivam takve odgovore parnom lokomotivom. U svakom slu\u010daju, 1024 poruka od 1 MB je bolje od jedne poruke veli\u010dine 1 GB. <\/p>\n<p><\/p>\n<p>U Erlang klasteru dobivamo dodatnu prednost - smanjenje optere\u0107enja na to\u010dki razmjene i mre\u017ei, jer se odgovori odmah upu\u0107uju primatelju, zaobilaze\u0107i to\u010dku razmjene.<\/p>\n<p><\/p>\n<h3 id=\"response-with-request\">Odziv z zahtevo<\/h3>\n<p><\/p>\n<p>To je prili\u010dno rijetka modifikacija RPC uzorka za izgradnju dijaloga sustava.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Gradniki porazdeljenih aplikacij. Prvo pribli\u017eno\" 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\">Objavi-pretplati (stabla distribucije podataka)<\/h3>\n<p><\/p>\n<p>Sustavi temeljen na doga\u0111ajima isporu\u010duju podatke potro\u0161a\u010dima \u010dim su dostupni. Na taj na\u010din, sustavi su skloniji push modelu nego pull ili poll. Ova karakteristika omogu\u0107ava da se resursi ne tro\u0161e uzalud stalnim zahtjevima i \u010dekanjem podataka.<br \/>\nNa slici je prikazan proces distribucije poruka potro\u0161a\u010dima koji su se prijavili na odre\u0111enu temu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Gradniki porazdeljenih aplikacij. Prvo pribli\u017eno\" src=\"\/wp-content\/uploads\/2019\/04\/e211d5dcfeb5ce8513699eac8e3b6d84.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Klasi\u010dni primjeri kori\u0161tenja ovog uzorka su distribucija stanja: svijeta igara u ra\u010dunalnim igrama, tr\u017ei\u0161nih podataka na burzama, korisnih informacija u podacima.<\/p>\n<p><\/p>\n<p>Pogledajmo kod pretplatnika:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">init(_Args) -&gt;\n  %% pretpla\u0107ujemo se na razmjenu, klju\u010d = key\n  messaging:subscribe(?SUBSCRIPTION, key, tag, self()),\n  {ok, #{}}.\n\nhandle_info(#exchange_die{exchange = ?SUBSCRIPTION}, State) -&gt;\n  %% ako to\u010dka razmjene nije dostupna, poku\u0161avamo ponovo povezati\n  messaging:subscribe(?SUBSCRIPTION, key, tag, self()),\n  {noreply, State};\n\n%% obra\u0111ujemo dolazne poruke\nhandle_info(#'$msg'{exchange = ?SUBSCRIPTION, message = Msg}, State) -&gt;\n  ?debugVal(Msg),\n  {noreply, State};\n\n%% prilikom zaustavljanja potro\u0161a\u010da isklju\u010dujemo se iz razmjene\nterminate(_Reason, _State) -&gt;\n  messaging:unsubscribe(?SUBSCRIPTION, key, tag, self()),\n  ok.<\/code><\/pre>\n<p><\/p>\n<p>Vir se lahko spro\u017ei funkcijo objave sporo\u010dila kjerkoli je to primerno:<\/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 ime izmenjevalne to\u010dke,<br \/>\n<em>Klju\u010d<\/em> \u2012 usmerjevalni klju\u010d<br \/>\n<em>Sporo\u010dilo<\/em> \u2012 obremenitev<\/p>\n<p><\/p>\n<h2 id=\"inverted-publish-subscribe\">Inverzno objavi-naro\u010di<\/h2>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Gradniki porazdeljenih aplikacij. Prvo pribli\u017eno\" src=\"\/wp-content\/uploads\/2019\/04\/2ef7cd7de459455937bdcfa8a11fd028.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Z uvedbo pub-sub dobimo vzorec, ki je priro\u010den za bele\u017eenje. Skupina virov in potro\u0161nikov je lahko popolnoma razli\u010dna. Na sliki je prikazan primer s enim potro\u0161nikom in ve\u010d viri.<\/p>\n<p><\/p>\n<h2 id=\"task-distribution-pattern\">Vzorec porazdelitve nalog<\/h2>\n<p><\/p>\n<p>V skoraj vsakem projektu se pojavijo naloge odlo\u017eene obdelave, kot so sestavljanje poro\u010dil, dostava obvestil, pridobivanje podatkov iz zunanjih sistemov. Preko dodajanja obdelovalcev je enostavno skalirati zmogljivost sistema, ki te naloge izvaja. Edino, kar nam preostane, je, da oblikujemo grozd obdelovalcev in naloge enakomerno porazdelimo med njimi.<\/p>\n<p><\/p>\n<p>Poglejmo nastale situacije na primeru 3 obdelovalcev. \u017de v fazi porazdelitve nalog se pojavi vpra\u0161anje pravi\u010dne razporeditve in preobremenitve obdelovalcev. Za pravi\u010dnost bo skrbelo porazdelitev po metodi round-robin, da se prepre\u010di preobremenitev obdelovalcev, pa uvedimo omejitev <em>prefetch_limit<\/em>. V prehodnih re\u017eimih <em>prefetch_limit<\/em> ne bo dovolila enemu obdelovalcu, da dobi vse naloge.<\/p>\n<p><\/p>\n<p>Messaging upravlja z vrsticami in prioritetami obdelave. Obdelovalci prejmejo naloge, ko te pridejo. Izvedba naloge se lahko zaklju\u010di uspe\u0161no ali pa z neuspehom:<\/p>\n<p><\/p>\n<ul>\n<li><code>messaging:ack(Tack)<\/code> \u2012 se kli\u010de v primeru uspe\u0161ne obdelave sporo\u010dila<\/li>\n<li><code>messaging:nack(Tack)<\/code> \u2012 se kli\u010de v vseh nenadnih situacijah. Po vrnitvi naloge messaging jo bo posredoval drugemu obdelovalcu.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Gradniki porazdeljenih aplikacij. Prvo pribli\u017eno\" src=\"\/wp-content\/uploads\/2019\/04\/c2c632b6411247ee8b0dcfb3250a4503.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Domnevajmo, da se je pri obdelavi treh nalog zgodila zapletena napaka: obdelovalec 1 se je po prejemu naloge zru\u0161il, ne da bi obve\u0161\u010dal izmenjevalno to\u010dko. V tem primeru bo izmenjevalna to\u010dka po preteku ack timeout prenesla nalogo drugemu obdelovalcu. Obdelovalec 3 se je iz nekega razloga odpovedal nalogi in poslal nack, zato je naloga prav tako pre\u0161la drugemu obdelovalcu, ki jo je uspe\u0161no izvedel.<\/p>\n<p><\/p>\n<h2 id=\"predvaritelnyy-itog\">Predhodni povzetek<\/h2>\n<p><\/p>\n<p>Obravnavali smo osnovne gradnike razdistributed sistemov in pridobili osnovno razumevanje njihove uporabe v Erlang\/Elixir.<\/p>\n<p><\/p>\n<p>S kombiniranjem osnovnih vzorcev je mogo\u010de oblikovati kompleksne paradigme za re\u0161evanje nastalih nalog.<\/p>\n<p><\/p>\n<p>V zaklju\u010dnem delu cikla bomo obravnavali splo\u0161na vpra\u0161anja organizacije storitev, usmerjanja in uravnote\u017eenja, ter spregovorili o prakti\u010dni strani raz\u0161irljivosti in odpornosti sistemov.<\/p>\n<p><\/p>\n<p>Konec drugega dela.<\/p>\n<p><\/p>\n<p>Fotografija <noindex>Marius Christensen<\/noindex><br \/>\nIlustracije so pripravljene s pomo\u010djo websequencediagrams.com<\/p>\n<p>Izvor: <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.4 - 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\/sl\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"sl_SI\" \/>\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\/sl\/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\udd47Gradniki distribuiranih aplikacij. Prvi pribli\u017eek | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sl_SI","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\/sl\/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\/sl\/wp-json\/wp\/v2\/posts\/30908","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/comments?post=30908"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts\/30908\/revisions"}],"predecessor-version":[{"id":162009,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts\/30908\/revisions\/162009"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media\/22886"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media?parent=30908"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/categories?post=30908"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/tags?post=30908"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}