{"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\/cs\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie","title":{"rendered":"Stavebn\u00ed bloky distribuovan\u00fdch aplikac\u00ed. Prvn\u00ed p\u0159ibl\u00ed\u017een\u00ed","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Stavebn\u00ed bloky distribuovan\u00fdch aplikac\u00ed. Prvn\u00ed p\u0159ibl\u00ed\u017een\u00ed\" src=\"\/wp-content\/uploads\/2019\/04\/7ef485e452075775ce317b557671274c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>V minulosti <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446028\/\">\u010dl\u00e1nku<\/a><\/noindex> Rozebrali jsme teoretick\u00e9 z\u00e1klady reaktivn\u00ed architektury. P\u0159i\u0161el \u010das mluvit o tok\u00e1ch dat, cest\u00e1ch realizace reaktivn\u00edch syst\u00e9m\u016f Erlang\/Elixir a vzorech v\u00fdm\u011bny zpr\u00e1v v nich:<\/p>\n<p><\/p>\n<ul>\n<li>\u017d\u00e1dost-odpov\u011b\u010f<\/li>\n<li>\u017d\u00e1dost-Chunked Odpov\u011b\u010f<\/li>\n<li>Odpov\u011b\u010f se \u017e\u00e1dost\u00ed<\/li>\n<li>Publikovat-p\u0159ihl\u00e1sit se<\/li>\n<li>Inverzn\u00ed publikov\u00e1n\u00ed-p\u0159ihla\u0161ov\u00e1n\u00ed<\/li>\n<li>Distribuce \u00faloh<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"soa-msa-i-obmen-soobscheniyami\">SOA, MSA a v\u00fdm\u011bna zpr\u00e1v<\/h2>\n<p><\/p>\n<p>SOA, MSA \u2013 syst\u00e9mov\u00e9 architektury, kter\u00e9 definuj\u00ed pravidla pro stavbu syst\u00e9m\u016f, zat\u00edmco messaging poskytuje primitiva pro jejich realizaci.<\/p>\n<p><\/p>\n<p>Nechci prosazovat \u017e\u00e1dnou konkr\u00e9tn\u00ed architekturu pro stavbu syst\u00e9m\u016f. Podporuji maxim\u00e1ln\u011b efektivn\u00ed a u\u017eite\u010dn\u00e9 praktiky pro konkr\u00e9tn\u00ed projekt a podnik\u00e1n\u00ed. A\u0165 u\u017e zvol\u00edme jakoukoli paradigmu, je lep\u0161\u00ed vytv\u00e1\u0159et syst\u00e9mov\u00e9 bloky s ohledem na Unixov\u00fd zp\u016fsob: komponenty s minim\u00e1ln\u00ed vazbou, kter\u00e9 odpov\u00eddaj\u00ed za jednotliv\u00e9 entity. API metody vykon\u00e1vaj\u00ed co nejjednodu\u0161\u0161\u00ed akce s entitami.<\/p>\n<p><\/p>\n<p>Messaging \u2012 jak je z n\u00e1zvu jasn\u00e9 \u2012 je zprost\u0159edkovatel zpr\u00e1v. Jeho hlavn\u00edm c\u00edlem je p\u0159ij\u00edmat a odes\u00edlat zpr\u00e1vy. Je odpov\u011bdn\u00fd za rozhran\u00ed pro odes\u00edl\u00e1n\u00ed informac\u00ed, vytv\u00e1\u0159en\u00ed logick\u00fdch kan\u00e1l\u016f pro p\u0159enos informac\u00ed uvnit\u0159 syst\u00e9mu, sm\u011brov\u00e1n\u00ed a vyva\u017eov\u00e1n\u00ed, stejn\u011b jako zpracov\u00e1n\u00ed selh\u00e1n\u00ed na syst\u00e9mov\u00e9 \u00farovni.<br \/>\nVyv\u00edjen\u00fd messaging se neuch\u00e1z\u00ed o konkurenci s rabbitmq ani se jej nesna\u017e\u00ed nahradit. Jeho hlavn\u00ed rysy jsou:<\/p>\n<p><\/p>\n<ul>\n<li>Distribuce.<br \/>\nBod\u016f v\u00fdm\u011bny lze vytv\u00e1\u0159et na v\u0161ech uzlech clusteru, co nejbl\u00ed\u017ee k\u00f3du, kter\u00fd je pou\u017e\u00edv\u00e1.<\/li>\n<li>Jednoduchost.<br \/>\nZam\u011b\u0159en\u00ed na minimalizaci \u0161ablonov\u00e9ho k\u00f3du a pohodl\u00ed pou\u017eit\u00ed.<\/li>\n<li>Par\u00e1dn\u00ed v\u00fdkon.<br \/>\nNepokou\u0161\u00edme se zopakovat funk\u010dnost rabbitmq, ale vy\u010dle\u0148ujeme pouze architektonickou a transportn\u00ed vrstvu, kterou co nejjednodu\u0161eji v\u010dle\u0148ujeme do OTP, a t\u00edm minimalizujeme n\u00e1klady.<\/li>\n<li>Flexibilita.<br \/>\nKa\u017ed\u00e1 slu\u017eba m\u016f\u017ee spojovat \u0159adu vzor\u016f v\u00fdm\u011bny.<\/li>\n<li>Odolnost proti selh\u00e1n\u00ed zakotven\u00e1 v designu.<\/li>\n<li>\u0160k\u00e1lovatelnost.<br \/>\nMessaging roste spolu s aplikac\u00ed. S rostouc\u00edm zat\u00ed\u017een\u00edm lze p\u0159esunout body v\u00fdm\u011bny na samostatn\u00e9 stroje.<\/li>\n<\/ul>\n<p><\/p>\n<p><em>Pozn\u00e1mka.<\/em> Z hlediska organizace k\u00f3du jsou pro slo\u017eit\u00e9 syst\u00e9my na Erlang\/Elixir vhodn\u00e9 meta-projekty. V\u0161echen k\u00f3d projektu se nach\u00e1z\u00ed v jednom \u00falo\u017ei\u0161ti \u2012 umbrella projektu. P\u0159itom jsou mikroslu\u017eby maxim\u00e1ln\u011b izolovan\u00e9 a vykon\u00e1vaj\u00ed jednoduch\u00e9 operace, kter\u00e9 odpov\u00eddaj\u00ed samostatn\u00e9 entit\u011b. P\u0159i takov\u00e9m p\u0159\u00edstupu je snadn\u00e9 udr\u017eovat API cel\u00e9ho syst\u00e9mu, jednodu\u0161e prov\u00e1d\u011bt zm\u011bny, a pohodln\u011b ps\u00e1t unit a integra\u010dn\u00ed testy.<\/p>\n<p><\/p>\n<p>Slo\u017eky syst\u00e9mu komunikuj\u00ed p\u0159\u00edmo nebo prost\u0159ednictv\u00edm brokera. Z pohledu messagingu m\u00e1 ka\u017ed\u00e1 slu\u017eba n\u011bkolik \u017eivotn\u00edch f\u00e1z\u00ed:<\/p>\n<p><\/p>\n<ul>\n<li>Inicializace slu\u017eby.<br \/>\nV t\u00e9to f\u00e1zi doch\u00e1z\u00ed k konfiguraci a spu\u0161t\u011bn\u00ed prov\u00e1d\u011bc\u00edho procesu slu\u017eby a jej\u00edch z\u00e1vislost\u00ed.<\/li>\n<li>Vytvo\u0159en\u00ed v\u00fdm\u011bnn\u00e9ho bodu.<br \/>\nSlu\u017eba m\u016f\u017ee pou\u017e\u00edvat statick\u00fd v\u00fdm\u011bnn\u00fd bod definovan\u00fd v konfiguraci uzlu, nebo m\u016f\u017ee dynamicky vytv\u00e1\u0159et v\u00fdm\u011bnn\u00e9 body. <\/li>\n<li>Registrace slu\u017eby.<br \/>\nAby slu\u017eba mohla obsluhovat po\u017eadavky, je t\u0159eba ji registrovat na v\u00fdm\u011bnn\u00e9m bod\u011b.<\/li>\n<li>Norm\u00e1ln\u00ed fungov\u00e1n\u00ed.<br \/>\nSlu\u017eba vykon\u00e1v\u00e1 u\u017eite\u010dnou pr\u00e1ci.<\/li>\n<li>Ukon\u010den\u00ed \u010dinnosti.<br \/>\nExistuj\u00ed 2 zp\u016fsoby ukon\u010den\u00ed \u010dinnosti: standardn\u00ed a havarijn\u00ed. P\u0159i standardn\u00edm ukon\u010den\u00ed se slu\u017eba odpoj\u00ed od v\u00fdm\u011bnn\u00e9ho bodu a zastav\u00ed se. V p\u0159\u00edpad\u011b havarijn\u00edch situac\u00ed messaging prov\u00e1d\u00ed jeden z sc\u00e9n\u00e1\u0159\u016f zpracov\u00e1n\u00ed poruch.<\/li>\n<\/ul>\n<p><\/p>\n<p>Vypad\u00e1 to docela slo\u017eit\u011b, ale v k\u00f3du to nen\u00ed tak \u0161patn\u00e9. P\u0159\u00edklady k\u00f3du s koment\u00e1\u0159i budou uvedeny p\u0159i rozboru \u0161ablon o n\u011bco pozd\u011bji.<\/p>\n<p><\/p>\n<h2 id=\"exchanges\">Exchanges<\/h2>\n<p><\/p>\n<p>V\u00fdm\u011bnn\u00fd bod \u2012 proces messaging, kter\u00fd implementuje logiku interakce s komponenty v r\u00e1mci \u0161ablony v\u00fdm\u011bny zpr\u00e1v. Ve v\u0161ech p\u0159\u00edkladech uveden\u00fdch n\u00ed\u017ee komponenty komunikuj\u00ed prost\u0159ednictv\u00edm v\u00fdm\u011bnn\u00fdch bod\u016f, jejich\u017e kombinace tvo\u0159\u00ed messaging.<\/p>\n<p><\/p>\n<h2 id=\"message-exchange-patterns-meps\">\u0160ablony v\u00fdm\u011bny zpr\u00e1v (MEPs)<\/h2>\n<p><\/p>\n<p>Glob\u00e1ln\u011b lze \u0161ablony v\u00fdm\u011bny rozd\u011blit na obousm\u011brn\u00e9 a jednostrann\u00e9. Prvn\u00ed p\u0159edpokl\u00e1daj\u00ed odpov\u011b\u010f na p\u0159ijatou zpr\u00e1vu, druh\u00e9 nikoli. Klasick\u00fdm p\u0159\u00edkladem obousm\u011brn\u00e9 \u0161ablony v architektu\u0159e klient-server je \u0161ablona Request-response. Pod\u00edvejme se na \u0161ablonu a jej\u00ed modifikace.<\/p>\n<p><\/p>\n<h3 id=\"requestresponse-ili-rpc\">Request\u2013response nebo RPC<\/h3>\n<p><\/p>\n<p>RPC se pou\u017e\u00edv\u00e1, kdy\u017e n\u00e1m pot\u0159ebujeme z\u00edskat odpov\u011b\u010f od jin\u00e9ho procesu. Tento proces m\u016f\u017ee b\u00fdt spu\u0161t\u011bn na stejn\u00e9 uzlu nebo se nach\u00e1zet na jin\u00e9m kontinentu. N\u00ed\u017ee je uveden diagram interakce klienta a <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/cs\/server\/dts-los-angeles\/\"   title=\"serveru\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"3483\">serveru<\/a> prost\u0159ednictv\u00edm messagingu.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Stavebn\u00ed bloky distribuovan\u00fdch aplikac\u00ed. Prvn\u00ed p\u0159ibl\u00ed\u017een\u00ed\" src=\"\/wp-content\/uploads\/2019\/04\/091725fc108d6ce1a5fc9ae866e2c395.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Proto\u017ee messaging je zcela asynchronn\u00ed, rozd\u011bluje se pro klienta v\u00fdm\u011bna na 2 f\u00e1ze:<\/p>\n<p><\/p>\n<ol>\n<li>\n<p>Odesl\u00e1n\u00ed po\u017eadavku<\/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 unik\u00e1tn\u00ed n\u00e1zev v\u00fdm\u011bnn\u00e9ho bodu<br \/>\n<em>ResponseMatchingTag<\/em> \u2012 lok\u00e1ln\u00ed zna\u010dka pro zpracov\u00e1n\u00ed odpov\u011bdi. Nap\u0159\u00edklad v p\u0159\u00edpad\u011b odesl\u00e1n\u00ed n\u011bkolika stejn\u00fdch \u017e\u00e1dost\u00ed pat\u0159\u00edc\u00edch r\u016fzn\u00fdm u\u017eivatel\u016fm.<br \/>\n<em>RequestDefinition<\/em> \u2012 t\u011blo \u017e\u00e1dosti<br \/>\n<em>HandlerProcess<\/em> \u2012 PID zpracovatele. Tento proces obdr\u017e\u00ed odpov\u011b\u010f od serveru.<\/p>\n<p>\n<\/li>\n<li>\n<p>Zpracov\u00e1n\u00ed odpov\u011bdi<\/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 odpov\u011b\u010f serveru.<\/p>\n<p>\n<\/li>\n<\/ol>\n<p><\/p>\n<p>Pro server proces tak\u00e9 sest\u00e1v\u00e1 ze 2 f\u00e1z\u00ed:<\/p>\n<p><\/p>\n<ol>\n<li>Inicializace v\u00fdm\u011bnn\u00e9ho bodu<\/li>\n<li>Zpracov\u00e1n\u00ed p\u0159\u00edchoz\u00edch \u017e\u00e1dost\u00ed<\/li>\n<\/ol>\n<p><\/p>\n<p>Ilustrujeme tento \u0161ablonov\u00fd k\u00f3d. P\u0159edpokl\u00e1dejme, \u017ee je t\u0159eba realizovat jednoduchou slu\u017ebu, kter\u00e1 poskytuje jedinou metodu p\u0159esn\u00e9ho \u010dasu.<\/p>\n<p><\/p>\n<h4 id=\"kod-servera\">K\u00f3d serveru<\/h4>\n<p><\/p>\n<p>Vyjmeme definici API slu\u017eby do api.hrl:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">%% =====================================================\n%%  entity\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%%  metody\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>Definujeme kontroler slu\u017eby v time_controller.erl<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">%% P\u0159\u00edklad ukazuje pouze v\u00fdznamn\u00fd k\u00f3d. Vlo\u017een\u00edm do \u0161ablony gen_server m\u016f\u017eete z\u00edskat funk\u010dn\u00ed slu\u017ebu.\n\n%% inicializace gen_server\ninit(Args) -&gt;\n  %% p\u0159ipojen\u00ed k v\u00fdm\u011bnn\u00e9mu bodu\n  messaging:monitor_exchange(req_resp, ?EXCHANGE, default, self())\n  {ok, #{}}.\n\n%% zpracov\u00e1n\u00ed ud\u00e1losti ztr\u00e1ty spojen\u00ed s v\u00fdm\u011bnn\u00fdm bodem. Tato ud\u00e1lost p\u0159ich\u00e1z\u00ed tak\u00e9, pokud v\u00fdm\u011bnn\u00fd bod je\u0161t\u011b nebyl spu\u0161t\u011bn.\nhandle_info(#exchange_die{exchange = ?EXCHANGE}, State) -&gt;\n  erlang:send(self(), monitor_exchange),\n  {noreply, State};\n\n%% zpracov\u00e1n\u00ed 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%% ukon\u010den\u00ed pr\u00e1ce 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\">K\u00f3d klienta<\/h4>\n<p><\/p>\n<p>Aby bylo mo\u017en\u00e9 odeslat \u017e\u00e1dost slu\u017eb\u011b, v jak\u00e9koli \u010d\u00e1sti klienta lze vyvolat API po\u017eadavku messaging:<\/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; %% opakovat nebo logika selh\u00e1n\u00ed\nend<\/code><\/pre>\n<p><\/p>\n<p>V distribuovan\u00e9m syst\u00e9mu m\u016f\u017ee b\u00fdt konfigurace komponent r\u016fzn\u00e1 a v okam\u017eiku \u017e\u00e1dosti m\u016f\u017ee messaging je\u0161t\u011b neb\u00fdt spu\u0161t\u011bn, nebo m\u016f\u017ee kontroler slu\u017eby b\u00fdt p\u0159ipraven obslou\u017eit \u017e\u00e1dost. Proto je nutn\u00e9 zkontrolovat odpov\u011b\u010f messaging a zpracovat p\u0159\u00edpad selh\u00e1n\u00ed.<br \/>\nPo \u00fasp\u011b\u0161n\u00e9m odesl\u00e1n\u00ed klient obdr\u017e\u00ed od slu\u017eby odpov\u011b\u010f nebo chybu.<br \/>\nZpracujeme ob\u011b situace v 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\">\u017d\u00e1dost-Chunked Odpov\u011b\u010f<\/h3>\n<p><\/p>\n<p>Lep\u0161\u00ed je zabr\u00e1nit p\u0159enosu obrovsk\u00fdch zpr\u00e1v. Na tom z\u00e1vis\u00ed reak\u010dn\u00ed doba a stabiln\u00ed provoz cel\u00e9ho syst\u00e9mu. Pokud odpov\u011b\u010f na po\u017eadavek zab\u00edr\u00e1 hodn\u011b pam\u011bti, rozd\u011blen\u00ed na \u010d\u00e1sti je nezbytn\u00e9.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Stavebn\u00ed bloky distribuovan\u00fdch aplikac\u00ed. Prvn\u00ed p\u0159ibl\u00ed\u017een\u00ed\" src=\"\/wp-content\/uploads\/2019\/04\/bd60742a933a8e4e3eeaf7f4adf00f2a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Uvedu n\u011bkolik p\u0159\u00edklad\u016f takov\u00fdch p\u0159\u00edpad\u016f:<\/p>\n<p><\/p>\n<ul>\n<li>Komponenty si vym\u011b\u0148uj\u00ed bin\u00e1rn\u00ed data, nap\u0159\u00edklad soubory. Rozd\u011blen\u00ed odpov\u011bdi na men\u0161\u00ed \u010d\u00e1sti pom\u00e1h\u00e1 efektivn\u011b pracovat se soubory jak\u00e9koliv velikosti a vyhnout se p\u0159ete\u010den\u00ed pam\u011bti.<\/li>\n<li>Seznamy. Nap\u0159\u00edklad pot\u0159ebujeme vybrat v\u0161echny z\u00e1znamy z obrovsk\u00e9 tabulky v datab\u00e1zi a p\u0159edat je jin\u00e9mu komponentu.<\/li>\n<\/ul>\n<p><\/p>\n<p>Naz\u00fdv\u00e1m takov\u00e9 odpov\u011bdi lokomotivou. V ka\u017ed\u00e9m p\u0159\u00edpad\u011b je 1024 zpr\u00e1v o velikosti 1 MB lep\u0161\u00ed ne\u017e jedin\u00e1 zpr\u00e1va o velikosti 1 GB. <\/p>\n<p><\/p>\n<p>V Erlang clusteru z\u00edsk\u00e1v\u00e1me dal\u0161\u00ed v\u00fdhodu \u2013 sn\u00ed\u017een\u00ed z\u00e1t\u011b\u017ee na v\u00fdm\u011bnn\u00e9m bodu a s\u00edti, proto\u017ee odpov\u011bdi jsou okam\u017eit\u011b sm\u011brov\u00e1ny k p\u0159\u00edjemci, obch\u00e1zej\u00edc v\u00fdm\u011bnn\u00fd bod.<\/p>\n<p><\/p>\n<h3 id=\"response-with-request\">Odpov\u011b\u010f se \u017e\u00e1dost\u00ed<\/h3>\n<p><\/p>\n<p>Jedn\u00e1 se o pom\u011brn\u011b vz\u00e1cnou modifikaci vzoru RPC pro vytv\u00e1\u0159en\u00ed dialogov\u00fdch syst\u00e9m\u016f.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Stavebn\u00ed bloky distribuovan\u00fdch aplikac\u00ed. Prvn\u00ed p\u0159ibl\u00ed\u017een\u00ed\" 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 (strom pro distribuci dat)<\/h3>\n<p><\/p>\n<p>Ud\u00e1lostmi \u0159\u00edzen\u00e9 syst\u00e9my dod\u00e1vaj\u00ed data spot\u0159ebitel\u016fm, jakmile jsou p\u0159ipravena. T\u00edmto zp\u016fsobem jsou syst\u00e9my v\u00edce naklon\u011bny push modelu ne\u017e pull nebo poll. Tato vlastnost umo\u017e\u0148uje neztr\u00e1cet zdroje neust\u00e1l\u00fdm dotazov\u00e1n\u00edm a \u010dek\u00e1n\u00edm na data.<br \/>\nNa obr\u00e1zku je zn\u00e1zorn\u011bn proces distribuce zpr\u00e1vy k spot\u0159ebitel\u016fm p\u0159ihl\u00e1\u0161en\u00fdm na ur\u010dit\u00e9 t\u00e9ma.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Stavebn\u00ed bloky distribuovan\u00fdch aplikac\u00ed. Prvn\u00ed p\u0159ibl\u00ed\u017een\u00ed\" src=\"\/wp-content\/uploads\/2019\/04\/e211d5dcfeb5ce8513699eac8e3b6d84.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Klasick\u00fdmi p\u0159\u00edklady pou\u017eit\u00ed t\u00e9to \u0161ablony je \u0161\u00ed\u0159en\u00ed stavu: hern\u00edho sv\u011bta v po\u010d\u00edta\u010dov\u00fdch hr\u00e1ch, tr\u017en\u00edch \u00fadaj\u016f na burz\u00e1ch, u\u017eite\u010dn\u00fdch informac\u00ed v datov\u00fdch toc\u00edch.<\/p>\n<p><\/p>\n<p>Pod\u00edvejme se na k\u00f3d p\u0159edplatitele:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">init(_Args) -&gt;\n  %% p\u0159ihla\u0161ujeme se k v\u00fdm\u011bnn\u00e9mu bodu, kl\u00ed\u010d = key\n  messaging:subscribe(?SUBSCRIPTION, key, tag, self()),\n  {ok, #{}}.\n\nhandle_info(#exchange_die{exchange = ?SUBSCRIPTION}, State) -&gt;\n  %% pokud je v\u00fdm\u011bnn\u00fd bod nedostupn\u00fd, pokus\u00edme se p\u0159ipojit zp\u011bt\n  messaging:subscribe(?SUBSCRIPTION, key, tag, self()),\n  {noreply, State};\n\n%% zpracov\u00e1v\u00e1me p\u0159ijat\u00e9 zpr\u00e1vy\nhandle_info(#'$msg'{exchange = ?SUBSCRIPTION, message = Msg}, State) -&gt;\n  ?debugVal(Msg),\n  {noreply, State};\n\n%% p\u0159i zastaven\u00ed spot\u0159ebitele - odpojujeme se od v\u00fdm\u011bnn\u00e9ho bodu\nterminate(_Reason, _State) -&gt;\n  messaging:unsubscribe(?SUBSCRIPTION, key, tag, self()),\n  ok.<\/code><\/pre>\n<p><\/p>\n<p>Zdroj m\u016f\u017ee spou\u0161t\u011bt funkci publikace zpr\u00e1vy kdekoli se to hod\u00ed:<\/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 n\u00e1zev bodu v\u00fdm\u011bny,<br \/>\n<em>Kl\u00ed\u010d<\/em> \u2012 kl\u00ed\u010d pro sm\u011brov\u00e1n\u00ed<br \/>\n<em>Zpr\u00e1va<\/em> \u2012 u\u017eite\u010dn\u00e9 zat\u00ed\u017een\u00ed<\/p>\n<p><\/p>\n<h2 id=\"inverted-publish-subscribe\">Inverzn\u00ed publikov\u00e1n\u00ed-p\u0159ihla\u0161ov\u00e1n\u00ed<\/h2>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Stavebn\u00ed bloky distribuovan\u00fdch aplikac\u00ed. Prvn\u00ed p\u0159ibl\u00ed\u017een\u00ed\" src=\"\/wp-content\/uploads\/2019\/04\/2ef7cd7de459455937bdcfa8a11fd028.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nasazen\u00edm pub-sub lze z\u00edskat vzor vhodn\u00fd pro logov\u00e1n\u00ed. Mno\u017eina zdroj\u016f a spot\u0159ebitel\u016f m\u016f\u017ee b\u00fdt zcela odli\u0161n\u00e1. Na obr\u00e1zku je uveden p\u0159\u00edpad s jedn\u00edm spot\u0159ebitelem a mnoha zdroji.<\/p>\n<p><\/p>\n<h2 id=\"task-distribution-pattern\">Vzorek distribuce \u00faloh<\/h2>\n<p><\/p>\n<p>V t\u00e9m\u011b\u0159 ka\u017ed\u00e9m projektu vznikaj\u00ed \u00fakoly odlo\u017een\u00e9ho zpracov\u00e1n\u00ed, jako nap\u0159\u00edklad generov\u00e1n\u00ed zpr\u00e1v, doru\u010dov\u00e1n\u00ed upozorn\u011bn\u00ed, z\u00edsk\u00e1v\u00e1n\u00ed dat ze t\u0159et\u00edch stran. Pr\u016fchodnost syst\u00e9mu, kter\u00fd tyto \u00fakoly vykon\u00e1v\u00e1, lze snadno \u0161k\u00e1lovat p\u0159id\u00e1v\u00e1n\u00edm zpracovatel\u016f. V\u0161e, co n\u00e1m zb\u00fdv\u00e1, je vytvo\u0159it cluster zpracovatel\u016f a rovnom\u011brn\u011b rozd\u011blit \u00fakoly mezi nimi.<\/p>\n<p><\/p>\n<p>Poj\u010fme se pod\u00edvat na vznikaj\u00edc\u00ed situace na p\u0159\u00edkladu 3 zpracovatel\u016f. Ji\u017e ve f\u00e1zi rozd\u011blov\u00e1n\u00ed \u00faloh se objevuje ot\u00e1zka spravedlnosti rozd\u011blen\u00ed a p\u0159epln\u011bn\u00ed zpracovatel\u016f. O spravedlnost se postar\u00e1 rozd\u011blen\u00ed round-robin, a aby se zabr\u00e1nilo situaci p\u0159epln\u011bn\u00ed zpracovatel\u016f, zavedeme limit <em>prefetch_limit<\/em>. V p\u0159echodn\u00fdch re\u017eimech <em>prefetch_limit<\/em> neumo\u017en\u00ed jednomu zpracovateli z\u00edskat v\u0161echny \u00fakoly.<\/p>\n<p><\/p>\n<p>Messaging \u0159\u00edd\u00ed fronty a priority zpracov\u00e1n\u00ed. Zpracovatel\u00e9 p\u0159ij\u00edmaj\u00ed \u00fakoly, jakmile p\u0159ich\u00e1zej\u00ed. Spln\u011bn\u00ed \u00fakolu m\u016f\u017ee skon\u010dit \u00fasp\u011bchem nebo selh\u00e1n\u00edm:<\/p>\n<p><\/p>\n<ul>\n<li><code>messaging:ack(Tack)<\/code> \u2012 je vyvol\u00e1no v p\u0159\u00edpad\u011b \u00fasp\u011b\u0161n\u00e9ho zpracov\u00e1n\u00ed zpr\u00e1vy<\/li>\n<li><code>messaging:nack(Tack)<\/code> \u2012 je vyvol\u00e1no ve v\u0161ech nouzov\u00fdch situac\u00edch. Po vr\u00e1cen\u00ed \u00fakolu messaging p\u0159ed\u00e1 \u00fakol jin\u00e9mu zpracovateli.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Stavebn\u00ed bloky distribuovan\u00fdch aplikac\u00ed. Prvn\u00ed p\u0159ibl\u00ed\u017een\u00ed\" src=\"\/wp-content\/uploads\/2019\/04\/c2c632b6411247ee8b0dcfb3250a4503.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>P\u0159edstavme si, \u017ee p\u0159i zpracov\u00e1n\u00ed t\u0159\u00ed \u00fakol\u016f do\u0161lo k komplikovan\u00e9mu selh\u00e1n\u00ed: zpracovatel 1 po p\u0159ijet\u00ed \u00fakolu selhal, ani\u017e by stihl cokoliv nahl\u00e1sit bodu v\u00fdm\u011bny. V tomto p\u0159\u00edpad\u011b bod v\u00fdm\u011bny po uplynut\u00ed ack timeout p\u0159ed\u00e1 \u00fakol jin\u00e9mu zpracovateli. Zpracovatel 3 se z n\u011bjak\u00e9ho d\u016fvodu vzdal \u00fakolu a poslal nack, nakonec \u00fakol p\u0159e\u0161el k jin\u00e9mu zpracovateli, kter\u00fd jej \u00fasp\u011b\u0161n\u011b splnil.<\/p>\n<p><\/p>\n<h2 id=\"predvaritelnyy-itog\">P\u0159edb\u011b\u017en\u00fd v\u00fdsledek<\/h2>\n<p><\/p>\n<p>Probrali jsme hlavn\u00ed stavebn\u00ed bloky distribuovan\u00fdch syst\u00e9m\u016f a z\u00edskali z\u00e1kladn\u00ed porozum\u011bn\u00ed jejich aplikaci v Erlang\/Elixir.<\/p>\n<p><\/p>\n<p>Kombinov\u00e1n\u00edm z\u00e1kladn\u00edch \u0161ablon lze sestavit slo\u017eit\u00e9 paradigmata pro \u0159e\u0161en\u00ed vznikaj\u00edc\u00edch \u00fakol\u016f.<\/p>\n<p><\/p>\n<p>V z\u00e1v\u011bre\u010dn\u00e9 \u010d\u00e1sti cyklu se pod\u00edv\u00e1me na obecn\u00e9 ot\u00e1zky organizace slu\u017eeb, sm\u011brov\u00e1n\u00ed a vyva\u017eov\u00e1n\u00ed z\u00e1t\u011b\u017ee, a tak\u00e9 se zam\u011b\u0159\u00edme na praktickou str\u00e1nku \u0161k\u00e1lovatelnosti a odolnosti syst\u00e9m\u016f.<\/p>\n<p><\/p>\n<p>Konec druh\u00e9 \u010d\u00e1sti.<\/p>\n<p><\/p>\n<p>Foto <noindex>Marius Christensen<\/noindex><br \/>\nIlustrace p\u0159ipraveny pomoc\u00ed websequencediagrams.com<\/p>\n<p>Zdroj: <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.3 - 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\/cs\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"cs_CZ\" \/>\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\/cs\/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\udd47Stavebn\u00ed bloky distribuovan\u00fdch aplikac\u00ed. Prvn\u00ed p\u0159\u00edstup | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/cs\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"cs_CZ","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\/cs\/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\/cs\/wp-json\/wp\/v2\/posts\/30908","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/comments?post=30908"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/30908\/revisions"}],"predecessor-version":[{"id":162009,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/posts\/30908\/revisions\/162009"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media\/22886"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/media?parent=30908"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/categories?post=30908"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/cs\/wp-json\/wp\/v2\/tags?post=30908"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}