{"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\/sq\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie","title":{"rendered":"Nd\u00ebrtesat e aplikacioneve t\u00eb shp\u00ebrndara. Qasja e par\u00eb","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Nd\u00ebrtesat e aplikacioneve t\u00eb shp\u00ebrndara. Qasja e par\u00eb\" src=\"\/wp-content\/uploads\/2019\/04\/7ef485e452075775ce317b557671274c.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>N\u00eb t\u00eb kaluar\u00ebn <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/446028\/\">artikulli yn\u00eb<\/a><\/noindex> Kemi analizuar teorit\u00eb themelore t\u00eb arkitektur\u00ebs reaktive. Ka ardhur koha t\u00eb flasim p\u00ebr grat\u00eb e t\u00eb dh\u00ebnave, rrug\u00ebt e realizimit t\u00eb sistemeve reaktive Erlang\/Elixir dhe modelet e shk\u00ebmbimit t\u00eb mesazheve n\u00eb to:<\/p>\n<p><\/p>\n<ul>\n<li>Request-response<\/li>\n<li>Request-Chunked Response<\/li>\n<li>Response with Request<\/li>\n<li>Publish-subscribe<\/li>\n<li>Inverted Publish-subscribe<\/li>\n<li>Task distribution<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/li>\n<\/ul>\n<p><\/p>\n<h2 id=\"soa-msa-i-obmen-soobscheniyami\">SOA, MSA dhe shk\u00ebmbimi i mesazheve<\/h2>\n<p><\/p>\n<p>SOA, MSA jan\u00eb arkitekturat sistemore q\u00eb p\u00ebrcaktojn\u00eb rregullat e nd\u00ebrtimit t\u00eb sistemeve, nd\u00ebrsa messaging ofron primitive p\u00ebr realizimin e tyre.<\/p>\n<p><\/p>\n<p>Nuk d\u00ebshiroj t\u00eb propagandoj asnj\u00eb arkitektur\u00eb n\u00eb nd\u00ebrtimin e sistemeve. Un\u00eb jam p\u00ebr aplikimin e praktikave m\u00eb t\u00eb efektshme dhe t\u00eb dobishme p\u00ebr projektin dhe biznesin specifik. Pa marr\u00eb parasysh paradigmat q\u00eb zgjedhim, \u00ebsht\u00eb m\u00eb mir\u00eb t\u00eb krijojm\u00eb blloqet sistemore duke u mb\u00ebshtetur n\u00eb Unix-way: komponimet me lidhje minime, q\u00eb p\u00ebrgjigjen p\u00ebr entitetet e ve\u00e7anta. Metodat API realizojn\u00eb veprime maksimalisht t\u00eb thjeshta me entitetet.<\/p>\n<p><\/p>\n<p>Messaging \u2012 si\u00e7 kuptohet nga emri \u2012 \u00ebsht\u00eb brokeri i mesazheve. Q\u00ebllimi i tij kryesor \u00ebsht\u00eb t\u00eb pranoj\u00eb dhe t\u00eb d\u00ebrgoj\u00eb mesazhe. Ai \u00ebsht\u00eb p\u00ebrgjegj\u00ebs p\u00ebr nd\u00ebrfaqet e d\u00ebrgimit t\u00eb informacionit, formimin e kanaleve logjik\u00eb t\u00eb transmetimit t\u00eb informacionit brenda sistemit, rrug\u00ebzimin dhe balancimin, si dhe trajtimin e d\u00ebshtimeve n\u00eb nivelin sistemor.<br \/>\nMessaging q\u00eb po zhvillohet nuk p\u00ebrpiqet t\u00eb konkurroj\u00eb me rabbitmq ose ta z\u00ebvend\u00ebsoj\u00eb at\u00eb. Ve\u00e7orit\u00eb e tij kryesore jan\u00eb:<\/p>\n<p><\/p>\n<ul>\n<li>Distribuese.<br \/>\nPikat e shk\u00ebmbimit mund t\u00eb krijohen n\u00eb t\u00eb gjitha nyjat e klasterit, sa m\u00eb af\u00ebr me kodin q\u00eb i p\u00ebrdor ato.<\/li>\n<li>Thjesht\u00ebsia.<br \/>\nOrientimi drejt minimizimit t\u00eb kodit model dhe leht\u00ebsis\u00eb n\u00eb p\u00ebrdorim.<\/li>\n<li>Performanca m\u00eb e mir\u00eb.<br \/>\nNe nuk p\u00ebrpiqemi t\u00eb p\u00ebrs\u00ebrisim funksionalitetin e rabbitmq, por p\u00ebrqendrohemi vet\u00ebm n\u00eb nivelin arkitekturor dhe t\u00eb transportit, q\u00eb t\u00eb integrohet sa m\u00eb thjesht n\u00eb OTP, duke minimizuar kostot.<\/li>\n<li>Fleksibiliteti.<br \/>\n\u00c7do sh\u00ebrbim mund t\u00eb p\u00ebrfshij\u00eb shum\u00eb modele shk\u00ebmbimi.<\/li>\n<li>Q\u00ebndrueshm\u00ebri n\u00eb rast d\u00ebshtimi, e integruar n\u00eb dizajn.<\/li>\n<li>Shkall\u00ebzimi.<br \/>\nMessaging rritet s\u00eb bashku me aplikacionin. Me rritjen e ngarkes\u00ebs, mund t\u00eb transferohen pikat e shk\u00ebmbimit n\u00eb makina t\u00eb ve\u00e7anta.<\/li>\n<\/ul>\n<p><\/p>\n<p><em>V\u00ebrejtje.<\/em> Nga pik\u00ebpamja e organizat\u00ebs s\u00eb kodit, p\u00ebr sistemet komplekse n\u00eb Erlang\/Elixir metaprojektet jan\u00eb shum\u00eb t\u00eb p\u00ebrshtatshme. E gjith\u00eb kodi i projektit ndodhet n\u00eb nj\u00eb depo \u2012 projektin n\u00ebn \u00e7ad\u00ebr. Duke e b\u00ebr\u00eb k\u00ebt\u00eb, mikrosh\u00ebrbimet jan\u00eb maksimalisht t\u00eb izoluara dhe kryejn\u00eb operacione t\u00eb thjeshta, p\u00ebrgjegj\u00ebse p\u00ebr nj\u00eb entitet t\u00eb ve\u00e7ant\u00eb. Me k\u00ebt\u00eb qasje, \u00ebsht\u00eb e leht\u00eb t\u00eb mbash API-n\u00eb er\u00eb, t\u00eb b\u00ebsh ndryshime dhe t\u00eb shkruash teste unike dhe integruese.<\/p>\n<p><\/p>\n<p>Komponent\u00ebt e sistemit nd\u00ebrlidhen drejtp\u00ebrdrejt ose p\u00ebrmes nj\u00eb brokeri. Nga pozita e mesazheve, \u00e7do sh\u00ebrbim ka disa faza t\u00eb jet\u00ebs:<\/p>\n<p><\/p>\n<ul>\n<li>Inicimi i sh\u00ebrbimit.<br \/>\nN\u00eb k\u00ebt\u00eb faz\u00eb ndodhin konfigurimi dhe nisja e procesit ekzekutues t\u00eb sh\u00ebrbimit dhe var\u00ebsive t\u00eb tij.<\/li>\n<li>Krijimi i pik\u00ebs s\u00eb shk\u00ebmbimit.<br \/>\nSh\u00ebrbimi mund t\u00eb p\u00ebrdor\u00eb nj\u00eb pik\u00eb shk\u00ebmbimi statike, t\u00eb caktuar n\u00eb konfigurimin e nodit, ose t\u00eb krijoj\u00eb pik\u00eb shk\u00ebmbimi dinamikisht. <\/li>\n<li>Regjistrimi i sh\u00ebrbimit.<br \/>\nQ\u00eb sh\u00ebrbimi t\u00eb mund t\u00eb sh\u00ebrbej\u00eb k\u00ebrkesat, ai duhet t\u00eb regjistrohet n\u00eb pik\u00ebn e shk\u00ebmbimit.<\/li>\n<li>Funksionimi normal.<br \/>\nSh\u00ebrbimi kryen pun\u00ebn e nevojshme.<\/li>\n<li>P\u00ebrfundimi i pun\u00ebs.<br \/>\nKa dy lloje p\u00ebrfundimesh: standarde dhe emergjente. N\u00eb rastin standard, sh\u00ebrbimi \u00e7kombinohet nga pika e shk\u00ebmbimit dhe ndalet. N\u00eb raste emergjente, mesazhet realizojn\u00eb nj\u00eb nga skenar\u00ebt e p\u00ebrpunimit t\u00eb d\u00ebshtimeve.<\/li>\n<\/ul>\n<p><\/p>\n<p>Duket mjaft e komplikuar, por n\u00eb kod nuk \u00ebsht\u00eb aq e frikshme. Nj\u00eb shembuj kodi me komente do t\u00eb jepen n\u00eb analiz\u00ebn e modeleve m\u00eb von\u00eb.<\/p>\n<p><\/p>\n<h2 id=\"exchanges\">K\u00ebmbime<\/h2>\n<p><\/p>\n<p>Pika e shk\u00ebmbimit \u2012 nj\u00eb proces mesazhi, q\u00eb realizon logjik\u00ebn e nd\u00ebrveprimit me komponent\u00ebt brenda struktur\u00ebs s\u00eb shk\u00ebmbimit t\u00eb mesazheve. N\u00eb t\u00eb gjitha shembujt e paraqitur m\u00eb posht\u00eb, komponent\u00ebt nd\u00ebrveprojn\u00eb p\u00ebrmes pikave t\u00eb shk\u00ebmbimit, kombinimi i t\u00eb cilave krijon mesazhin.<\/p>\n<p><\/p>\n<h2 id=\"message-exchange-patterns-meps\">Modelet e shk\u00ebmbimit t\u00eb mesazheve (MEPs)<\/h2>\n<p><\/p>\n<p>Globalisht, modelet e shk\u00ebmbimit mund t\u00eb ndahen n\u00eb dyansh\u00ebm dhe nj\u00ebansh\u00ebm. T\u00eb parat p\u00ebrfshijn\u00eb nj\u00eb p\u00ebrgjigje ndaj mesazhit t\u00eb pranuar, nd\u00ebrsa t\u00eb dyjat jo. Nj\u00eb shembull klasik i nj\u00eb modeli dyansh\u00ebm n\u00eb arkitektur\u00ebn klient-server \u00ebsht\u00eb modeli i K\u00ebrkes\u00eb-p\u00ebrgjigje. Le t\u00eb shqyrtojm\u00eb modelin dhe modifikimet e tij.<\/p>\n<p><\/p>\n<h3 id=\"requestresponse-ili-rpc\">K\u00ebrkes\u00eb-p\u00ebrgjigje ose RPC<\/h3>\n<p><\/p>\n<p>RPC p\u00ebrdoret kur na nevojitet t\u00eb marrim nj\u00eb p\u00ebrgjigje nga nj\u00eb proces tjet\u00ebr. Ky proces mund t\u00eb jet\u00eb i nisur n\u00eb t\u00eb nj\u00ebjtin nod apo t\u00eb jet\u00eb n\u00eb nj\u00eb kontinent tjet\u00ebr. M\u00eb posht\u00eb paraqitet skema e nd\u00ebrveprimit t\u00eb klientit dhe <a class=\"wpil_keyword_link\" href=\"https:\/\/prohoster.info\/sq\/server\/dts-los-angeles\/\"   title=\"server\u00eb\" data-wpil-keyword-link=\"linked\"  data-wpil-monitor-id=\"3483\">server\u00eb<\/a> p\u00ebrmes mesazheve.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Nd\u00ebrtesat e aplikacioneve t\u00eb shp\u00ebrndara. Qasja e par\u00eb\" src=\"\/wp-content\/uploads\/2019\/04\/091725fc108d6ce1a5fc9ae866e2c395.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Duke qen\u00eb se mesazhi \u00ebsht\u00eb plot\u00ebsisht asinkron, p\u00ebr klientin shk\u00ebmbimi ndahet n\u00eb 2 faza:<\/p>\n<p><\/p>\n<ol>\n<li>\n<p>D\u00ebrgimi i k\u00ebrkes\u00ebs<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">mesazhimi: k\u00ebrkes\u00eb(Exchange, ResponseMatchingTag, RequestDefinition, HandlerProcess).<\/code><\/pre>\n<p><\/p>\n<p><em>Shk\u00ebmbim<\/em> \u2012 emri unik i pik\u00ebs s\u00eb shk\u00ebmbimit<br \/>\n<em>ResponseMatchingTag<\/em> \u2012 etiket\u00eb lokale p\u00ebr p\u00ebrpunimin e p\u00ebrgjigjes. P\u00ebr shembull, n\u00eb rast se d\u00ebrgojm\u00eb disa k\u00ebrkesa identike, t\u00eb cilat iu takojn\u00eb p\u00ebrdoruesve t\u00eb ndrysh\u00ebm.<br \/>\n<em>RequestDefinition<\/em> \u2012 trupi i k\u00ebrkes\u00ebs<br \/>\n<em>HandlerProcess<\/em> \u2012 PID-i i p\u00ebrpunuesit. Ky proces do t\u00eb marr\u00eb p\u00ebrgjigjen nga serveri.<\/p>\n<p>\n<\/li>\n<li>\n<p>P\u00ebrpunimi i p\u00ebrgjigjes<\/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 p\u00ebrgjigja e serverit.<\/p>\n<p>\n<\/li>\n<\/ol>\n<p><\/p>\n<p>P\u00ebr serverin, procesi p\u00ebrb\u00ebhet gjithashtu nga 2 faza:<\/p>\n<p><\/p>\n<ol>\n<li>Inizializimi i pik\u00ebs s\u00eb shk\u00ebmbimit<\/li>\n<li>P\u00ebrpunimi i k\u00ebrkesave t\u00eb marra<\/li>\n<\/ol>\n<p><\/p>\n<p>T\u00eb ilustrojm\u00eb k\u00ebt\u00eb model me kod. Le t\u00eb supozojm\u00eb se duhet t\u00eb realizojm\u00eb nj\u00eb sh\u00ebrbim t\u00eb thjesht\u00eb, i cili ofron vet\u00ebm nj\u00eb metod\u00eb p\u00ebr koh\u00ebn e sakt\u00eb.<\/p>\n<p><\/p>\n<h4 id=\"kod-servera\">Kodi i serverit<\/h4>\n<p><\/p>\n<p>Do ta nxjerrim p\u00ebrcaktimin e API-s\u00eb s\u00eb sh\u00ebrbimit n\u00eb api.hrl:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">%% =====================================================\n%%  entitetet\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%%  metodat\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>Do ta p\u00ebrcaktojm\u00eb kontrolluesin e sh\u00ebrbimit n\u00eb time_controller.erl<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">%% N\u00eb k\u00ebt\u00eb shembull tregohet vet\u00ebm kodi i r\u00ebnd\u00ebsish\u00ebm. Duke e vendosur at\u00eb n\u00eb modelin gen_server, mund t\u00eb marrim nj\u00eb sh\u00ebrbim funksional.\n\n%% inizializimi i gen_server\ninit(Args) -&gt;\n  %% lidhja me pik\u00ebn e shk\u00ebmbimit\n  messaging:monitor_exchange(req_resp, ?EXCHANGE, default, self())\n  {ok, #{}}.\n\n%% p\u00ebrpunimi i ngjarjeve t\u00eb humbjes s\u00eb lidhjes me pik\u00ebn e shk\u00ebmbimit. Ky \u00ebsht\u00eb gjithashtu ngjarja q\u00eb vjen n\u00ebse pika e shk\u00ebmbimit nuk ka filluar ende.\nhandle_info(#exchange_die{exchange = ?EXCHANGE}, State) -&gt;\n  erlang:send(self(), monitor_exchange),\n  {noreply, State};\n\n%% p\u00ebrpunimi i API-s\u00eb\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%% p\u00ebrfundimi i pun\u00ebs s\u00eb 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\">Kodi i klientit<\/h4>\n<p><\/p>\n<p>P\u00ebr t\u00eb d\u00ebrguar nj\u00eb k\u00ebrkes\u00eb n\u00eb sh\u00ebrbim, n\u00eb \u00e7do vend t\u00eb klientit mund t\u00eb th\u00ebrrasim API-n\u00eb e k\u00ebrkes\u00ebs s\u00eb messaging:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">rast messaging:request(?EXCHANGE, tag, #time_req{opts = #{}}, self()) nga\n    ok -&gt; ok;\n    _ -&gt; %% logjika e p\u00ebrs\u00ebritjes ose d\u00ebshtimit\nfund<\/code><\/pre>\n<p><\/p>\n<p>N\u00eb nj\u00eb sistem t\u00eb shp\u00ebrndar\u00eb, konfigurimi i komponent\u00ebve mund t\u00eb jet\u00eb i ndrysh\u00ebm dhe n\u00eb momentin e k\u00ebrkes\u00ebs, messaging mund t\u00eb mos ket\u00eb filluar akoma, ose kontrolluesi i sh\u00ebrbimit mund t\u00eb mos jet\u00eb gati p\u00ebr t\u00eb sh\u00ebrbyer k\u00ebrkes\u00ebn. Prandaj, \u00ebsht\u00eb e nevojshme t\u00eb verifikojm\u00eb p\u00ebrgjigjen e messaging dhe t\u00eb p\u00ebrpunojm\u00eb rastin e d\u00ebshtimit.<br \/>\nPas d\u00ebrgimit t\u00eb suksessh\u00ebm, klienti do t\u00eb marr\u00eb nj\u00eb p\u00ebrgjigje ose nj\u00eb gabim nga sh\u00ebrbimi.<br \/>\nDo t\u2019i p\u00ebrpunojm\u00eb t\u00eb dy rastet n\u00eb 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\">Request-Chunked Response<\/h3>\n<p><\/p>\n<p>\u00cbsht\u00eb m\u00eb mir\u00eb t\u00eb shmangni d\u00ebrgimin e mesazheve t\u00eb m\u00ebdha. Kjo ndikon n\u00eb p\u00ebrgjegjshm\u00ebrin\u00eb dhe stabilitetin e gjith\u00eb sistemit. N\u00ebse p\u00ebrgjigjja ndaj nj\u00eb k\u00ebrkese merr shum\u00eb memorie, at\u00ebher\u00eb ndarja n\u00eb pjes\u00eb \u00ebsht\u00eb e domosdoshme.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Nd\u00ebrtesat e aplikacioneve t\u00eb shp\u00ebrndara. Qasja e par\u00eb\" src=\"\/wp-content\/uploads\/2019\/04\/bd60742a933a8e4e3eeaf7f4adf00f2a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ja disa shembuj t\u00eb till\u00eb:<\/p>\n<p><\/p>\n<ul>\n<li>Komponent\u00ebt shk\u00ebmbejn\u00eb t\u00eb dh\u00ebna binare, p\u00ebr shembull skedar\u00eb. Ndarja e p\u00ebrgjigjes n\u00eb pjes\u00eb t\u00eb vogla ndihmon n\u00eb pun\u00ebn efikase me skedar\u00eb t\u00eb \u00e7do madh\u00ebsie dhe n\u00eb parandalimin e mbushjes s\u00eb memories.<\/li>\n<li>Listimet. P\u00ebr shembull, na nevojitet t\u00eb zgjedhim t\u00eb gjitha regjistrimet nga nj\u00eb tabel\u00eb t\u00eb madhe n\u00eb baz\u00eb dhe t'i d\u00ebrgojm\u00eb nj\u00eb komponenti tjet\u00ebr.<\/li>\n<\/ul>\n<p><\/p>\n<p>I quaj p\u00ebrgjigjet e tilla \u2018lokomotiva\u2019. N\u00eb \u00e7do rast, 1024 mesazhe prej 1 MB jan\u00eb m\u00eb mir\u00eb se nj\u00eb mesazh i vet\u00ebm me madh\u00ebsi 1 GB. <\/p>\n<p><\/p>\n<p>N\u00eb nj\u00eb klaster Erlang, ne fitojm\u00eb nj\u00eb avantazh shtes\u00eb - uljen e ngarkes\u00ebs n\u00eb pik\u00ebn e shk\u00ebmbimit dhe rrjet, pasi p\u00ebrgjigjet d\u00ebrgohen menj\u00ebher\u00eb tek marr\u00ebsi, duke anashkaluar pik\u00ebn e shk\u00ebmbimit.<\/p>\n<p><\/p>\n<h3 id=\"response-with-request\">Response with Request<\/h3>\n<p><\/p>\n<p>Kjo \u00ebsht\u00eb nj\u00eb modifikim mjaft i rrall\u00eb i modelit RPC p\u00ebr nd\u00ebrtimin e sistemeve dialoguese.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Nd\u00ebrtesat e aplikacioneve t\u00eb shp\u00ebrndara. Qasja e par\u00eb\" 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\">Publiko-abonimi (pema e shp\u00ebrndarjes s\u00eb t\u00eb dh\u00ebnave)<\/h3>\n<p><\/p>\n<p>Sistemet e orientuara nga ngjarjet dor\u00ebzojn\u00eb t\u00eb dh\u00ebnat te konsumatoret sipas gatishm\u00ebris\u00eb s\u00eb tyre. K\u00ebshtu, sistemet jan\u00eb m\u00eb t\u00eb prirura drejt modelit push sesa pull ose poll. Kjo ve\u00e7ori parandalon shpenzimin e burimeve duke k\u00ebrkuar dhe pritur vazhdimisht t\u00eb dh\u00ebna.<br \/>\nN\u00eb ilustrim jan\u00eb paraqitur proceset e shp\u00ebrndarjes s\u00eb mesazheve te konsumatoret q\u00eb jan\u00eb abonuar n\u00eb nj\u00eb tem\u00eb t\u00eb caktuar.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Nd\u00ebrtesat e aplikacioneve t\u00eb shp\u00ebrndara. Qasja e par\u00eb\" src=\"\/wp-content\/uploads\/2019\/04\/e211d5dcfeb5ce8513699eac8e3b6d84.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Shembujt klasik\u00eb t\u00eb p\u00ebrdorimit t\u00eb k\u00ebtij modeli jan\u00eb shp\u00ebrndarja e gjendjes: bot\u00ebs s\u00eb lojrave n\u00eb lojrat kompjuterike, t\u00eb dh\u00ebnave t\u00eb tregut n\u00eb burs\u00eb, informacionit t\u00eb dobish\u00ebm n\u00eb datafeed.<\/p>\n<p><\/p>\n<p>Le t\u00eb shqyrtojm\u00eb kodin e abonentit:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">init(_Args) -&gt;\n  %% abonohuni n\u00eb shk\u00ebmbimin, \u00e7el\u00ebsi = key\n  messaging:subscribe(?SUBSCRIPTION, key, tag, self()),\n  {ok, #{}}.\n\nhandle_info(#exchange_die{exchange = ?SUBSCRIPTION}, State) -&gt;\n  %% n\u00ebse pika e shk\u00ebmbimit nuk \u00ebsht\u00eb e available, p\u00ebrpiqemi t\u00eb rip\u00ebrqafojm\u00eb\n  messaging:subscribe(?SUBSCRIPTION, key, tag, self()),\n  {noreply, State};\n\n%% procesoni mesazhet q\u00eb vijn\u00eb\nhandle_info(#'$msg'{exchange = ?SUBSCRIPTION, message = Msg}, State) -&gt;\n  ?debugVal(Msg),\n  {noreply, State};\n\n%% kur ndalej konsumatori - shk\u00ebputemi nga pika e shk\u00ebmbimit\nterminate(_Reason, _State) -&gt;\n  messaging:unsubscribe(?SUBSCRIPTION, key, tag, self()),\n  ok.<\/code><\/pre>\n<p><\/p>\n<p>Burimi mund t\u00eb th\u00ebrras\u00eb funksionin e publikimit t\u00eb mesazheve n\u00eb \u00e7do vend t\u00eb p\u00ebrshtatsh\u00ebm:<\/p>\n<p><\/p>\n<pre><code class=\"erlang\">messaging:publish_message(Exchange, Key, Message).<\/code><\/pre>\n<p><\/p>\n<p><em>Shk\u00ebmbim<\/em> \u2012 emri i pik\u00ebs s\u00eb shk\u00ebmbimit,<br \/>\n<em>\u00c7el\u00ebsi<\/em> \u2012 \u00e7el\u00ebsi i \u043c\u0430\u0440\u0448\u0440\u0443\u0442izimit<br \/>\n<em>Mesazhi<\/em> \u2012 ngarkesa<\/p>\n<p><\/p>\n<h2 id=\"inverted-publish-subscribe\">Inverted Publish-subscribe<\/h2>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Nd\u00ebrtesat e aplikacioneve t\u00eb shp\u00ebrndara. Qasja e par\u00eb\" src=\"\/wp-content\/uploads\/2019\/04\/2ef7cd7de459455937bdcfa8a11fd028.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Duke zhvilluar pub-sub, mund t\u00eb arrijm\u00eb nj\u00eb model t\u00eb p\u00ebrshtatsh\u00ebm p\u00ebr regjistrim. Grupi i burimeve dhe konsumator\u00ebve mund t\u00eb jet\u00eb krejt\u00ebsisht i ndrysh\u00ebm. N\u00eb figur\u00eb tregohet rasti me nj\u00eb konsumator dhe shum\u00eb burime.<\/p>\n<p><\/p>\n<h2 id=\"task-distribution-pattern\">Modeli i shp\u00ebrndarjes s\u00eb detyrave<\/h2>\n<p><\/p>\n<p>N\u00eb almost \u00e7do projekt ndodhin detyra t\u00eb p\u00ebrpunimit t\u00eb shtyer, si\u00e7 jan\u00eb krijimi i raporteve, d\u00ebrgimi i njoftimeve, marrja e t\u00eb dh\u00ebnave nga sisteme t\u00eb jashtme. Kapaciteti i sistemit q\u00eb kryen k\u00ebto detyra leht\u00eb mund t\u00eb shkall\u00ebzohet duke shtuar p\u00ebrpunues. E vetmja gj\u00eb q\u00eb na mbetet \u00ebsht\u00eb t\u00eb formojm\u00eb nj\u00eb grup t\u00eb p\u00ebrpunuesve dhe t\u00eb shp\u00ebrndajm\u00eb detyrat nj\u00eblloj mes tyre.<\/p>\n<p><\/p>\n<p>Le t\u00eb shqyrtojm\u00eb situatat q\u00eb lindin me shembuj 3 p\u00ebrpunuesish. Edhe n\u00eb faz\u00ebn e shp\u00ebrndarjes s\u00eb detyrave lind pyetja e drejt\u00ebsis\u00eb s\u00eb shp\u00ebrndarjes dhe mbingarkes\u00ebs s\u00eb p\u00ebrpunuesve. Drejt\u00ebsia do t\u00eb garantohet nga shp\u00ebrndarja round-robin, dhe p\u00ebr t\u00eb parandaluar mbingarkes\u00ebn e p\u00ebrpunuesve, do t\u00eb vendosim nj\u00eb kufizim <em>prefetch_limit<\/em>. N\u00eb m\u00ebnyrat e kalimit <em>prefetch_limit<\/em> nuk do t\u00eb lejoj\u00eb nj\u00eb p\u00ebrpunues q\u00eb t\u00eb marr\u00eb t\u00eb gjitha detyrat.<\/p>\n<p><\/p>\n<p>Messaging menaxhon radh\u00ebt dhe prioritetin e p\u00ebrpunimit. P\u00ebrpunuesit marrin detyrat me kalimin e tyre. Ekzekutimi i nj\u00eb detyre mund t\u00eb p\u00ebrfundoj\u00eb me sukses ose me d\u00ebshtim:<\/p>\n<p><\/p>\n<ul>\n<li><code>messaging:ack(Tack)<\/code> \u2012 thirret n\u00eb rastin e p\u00ebrpunimit t\u00eb suksessh\u00ebm t\u00eb mesazhit<\/li>\n<li><code>messaging:nack(Tack)<\/code> \u2012 thirret n\u00eb t\u00eb gjitha situatat e jashtzakonshme. Pas kthimit t\u00eb detyr\u00ebs, messaging do ta kaloj\u00eb at\u00eb tek nj\u00eb p\u00ebrpunues tjet\u00ebr.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Nd\u00ebrtesat e aplikacioneve t\u00eb shp\u00ebrndara. Qasja e par\u00eb\" src=\"\/wp-content\/uploads\/2019\/04\/c2c632b6411247ee8b0dcfb3250a4503.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Le t\u00eb supozojm\u00eb se gjat\u00eb p\u00ebrpunimit t\u00eb tre detyrave ndodhi nj\u00eb d\u00ebshtim i nd\u00ebrlikuar: p\u00ebrpunuesi 1 pasi mori detyr\u00ebn ra, pa arritur t\u00eb njoftoj\u00eb asgj\u00eb n\u00eb pik\u00ebn e shk\u00ebmbimit. N\u00eb k\u00ebt\u00eb rast, pika e shk\u00ebmbimit pas skadimit t\u00eb koh\u00ebs p\u00ebr njohjen e miratimit do ta kaloj\u00eb detyr\u00ebn tek nj\u00eb p\u00ebrpunues tjet\u00ebr. P\u00ebrpunuesi 3 nga ndonj\u00eb arsye e refuzoi detyr\u00ebn dhe d\u00ebrgoi nack, si rezultat detyra gjithashtu kaloi tek nj\u00eb p\u00ebrpunues tjet\u00ebr q\u00eb e kreu me sukses.<\/p>\n<p><\/p>\n<h2 id=\"predvaritelnyy-itog\">P\u00ebrfundim paraprak<\/h2>\n<p><\/p>\n<p>Kemi shqyrtuar bloket thelb\u00ebsore t\u00eb sistemeve t\u00eb shp\u00ebrndara dhe kemi marr\u00eb nj\u00eb kuptim themelor t\u00eb aplikimit t\u00eb tyre n\u00eb Erlang\/Elixir.<\/p>\n<p><\/p>\n<p>Duke kombinuar modelet themelore, \u00ebsht\u00eb e mundur t\u00eb krijojm\u00eb paradigma komplekse p\u00ebr t\u00eb zgjidhur detyrat q\u00eb lindin.<\/p>\n<p><\/p>\n<p>N\u00eb pjes\u00ebn p\u00ebrfundimtare t\u00eb ciklit, ne do t\u00eb shqyrtojm\u00eb \u00e7\u00ebshtje t\u00eb p\u00ebrgjithshme rreth organizimit t\u00eb sh\u00ebrbimeve, ruterimit dhe balancimit, si dhe do t\u00eb flasim p\u00ebr an\u00ebn praktike t\u00eb shkall\u00ebzueshm\u00ebris\u00eb dhe q\u00ebndrueshm\u00ebris\u00eb s\u00eb sistemeve.<\/p>\n<p><\/p>\n<p>Fundi i pjes\u00ebs s\u00eb dyt\u00eb.<\/p>\n<p><\/p>\n<p>Foto <noindex>Marius Christensen<\/noindex><br \/>\nIlustrimet jan\u00eb p\u00ebrgatitur me ndihm\u00ebn e websequencediagrams.com<\/p>\n<p>Burimi: <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.2 - 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\/sq\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"sq_AL\" \/>\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\/sq\/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\udd47Blloqet nd\u00ebrtuese t\u00eb aplikacioneve t\u00eb shp\u00ebrndara. Qasje e par\u00eb | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/sq\/blog\/administrirovanie\/stroitelnye-bloki-raspredelennyh-prilozhenij-pervoe-priblizhenie","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sq_AL","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\/sq\/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\/sq\/wp-json\/wp\/v2\/posts\/30908","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/comments?post=30908"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/30908\/revisions"}],"predecessor-version":[{"id":162009,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/posts\/30908\/revisions\/162009"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media\/22886"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/media?parent=30908"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/categories?post=30908"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sq\/wp-json\/wp\/v2\/tags?post=30908"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}