{"id":80035,"date":"2020-05-02T13:42:54","date_gmt":"2020-05-02T11:42:54","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny"},"modified":"2020-05-02T13:42:54","modified_gmt":"2020-05-02T11:42:54","slug":"udobnye-arhitekturnye-patterny","status":"publish","type":"post","link":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny","title":{"rendered":"Prakti\u010dni arhitektonski obrasci","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Bok, Habr!<\/p>\n<p><\/p>\n<p>S obzirom na trenutne doga\u0111aje uzrokovane koronavirusom, nekoliko internetskih usluga po\u010delo je primati ve\u0107e optere\u0107enje. Na primjer, <noindex><a rel=\"nofollow\" href=\"https:\/\/www.independent.co.uk\/life-style\/gadgets-and-tech\/news\/coronavirus-ocado-down-app-website-stockpiling-food-online-delivery-a9402216.html\">jedna trgova\u010dka mre\u017ea u Ujedinjenom Kraljevstvu jednostavno je obustavila web stranicu s online narud\u017ebama<\/a><\/noindex>, jer nije bilo dovoljnih resursa. A nije uvijek mogu\u0107e ubrzati server jednostavno dodavanjem mo\u0107nijih ure\u0111aja, me\u0111utim, zahtjeve klijenata treba obraditi (ili \u0107e oti\u0107i konkurentima).<\/p>\n<p><\/p>\n<p>U ovom \u010dlanku \u0107u ukratko opisati popularne prakse koje omogu\u0107uju brzu i otpornu uslugu. Me\u0111utim, od svih mogu\u0107ih shema razvoja odabrao sam samo one koje su trenutno <strong>lako dostupne.<\/strong>Za svaku to\u010dku ve\u0107 imate pripremljene biblioteke ili mogu\u0107nost rje\u0161avanja zadatka putem obla\u010dne platforme.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1 id=\"gorizontalnoe-masshtabirovanie\">Horizontalno skaliranje<\/h1>\n<p><\/p>\n<p>Najjednostavnija i svima poznata to\u010dka. U principu, naj\u010de\u0161\u0107e se susre\u0107u dva schematska pristupa raspodjeli optere\u0107enja \u2014 horizontalno i vertikalno skaliranje. <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9C%D0%B0%D1%81%D1%88%D1%82%D0%B0%D0%B1%D0%B8%D1%80%D1%83%D0%B5%D0%BC%D0%BE%D1%81%D1%82%D1%8C#%D0%93%D0%BE%D1%80%D0%B8%D0%B7%D0%BE%D0%BD%D1%82%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BC%D0%B0%D1%81%D1%88%D1%82%D0%B0%D0%B1%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\">U prvom slu\u010daju<\/a><\/noindex> dopu\u0161tate uslugama da rade paralelno, \u010dime se raspore\u0111uje optere\u0107enje me\u0111u njima. <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9C%D0%B0%D1%81%D1%88%D1%82%D0%B0%D0%B1%D0%B8%D1%80%D1%83%D0%B5%D0%BC%D0%BE%D1%81%D1%82%D1%8C#%D0%92%D0%B5%D1%80%D1%82%D0%B8%D0%BA%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BC%D0%B0%D1%81%D1%88%D1%82%D0%B0%D0%B1%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5\">U drugom<\/a><\/noindex> naru\u010dujete mo\u0107nije servere ili optimizirate kod.<\/p>\n<p><\/p>\n<p>Za primjer \u0107u uzeti apstraktno obla\u010dno pohranjivanje datoteka, odnosno neki analog OwnCloud, OneDrive i sli\u010dno.<\/p>\n<p><\/p>\n<p>Standardna slika takve sheme je ispod, me\u0111utim ona samo prikazuje slo\u017eenost sustava. Naime, potrebno je na neki na\u010din sinkronizirati usluge. \u0160to \u0107e se dogoditi ako korisnik na tabletu spremi datoteku, a zatim je \u017eeli pregledati s telefona?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Prakti\u010dni arhitektonski obrasci\" src=\"\/wp-content\/uploads\/2020\/05\/7512c6d8783f5e0a38cc0861b01e54c8.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nRazlika izme\u0111u pristupa: u vertikalnom skaliranju spremni smo pove\u0107ati snagu \u010dvorova, dok u horizontalnom dodajemo nove \u010dvorove kako bismo rasporedili optere\u0107enje.<\/p>\n<p><\/p>\n<h1 id=\"cqrs\">CQRS<\/h1>\n<p><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/martinfowler.com\/bliki\/CQRS.html\">Razdvajanje odgovornosti za naredbe i upite<\/a><\/noindex> je prili\u010dno va\u017ean obrazac, jer omogu\u0107uje razli\u010ditim klijentima da se pove\u017eu s razli\u010ditim uslugama, ali i da primaju iste tokove doga\u0111aja. Njegove prednosti nisu toliko o\u010dite za jednostavne aplikacije, me\u0111utim, iznimno su va\u017ene (i jednostavne) za optere\u0107ene usluge. Njegova su\u0161tina: ulazni i izlazni tokovi podataka ne smiju se prekri\u017eiti. To jest, ne mo\u017eete poslati zahtjev i o\u010dekivati odgovor, umjesto toga \u0161aljete zahtjev u uslugu A, ali dobivate odgovor u usluzi B.<\/p>\n<p><\/p>\n<p>Prva prednost ovog pristupa je mogu\u0107nost prekida veze (u \u0161irokom smislu te rije\u010di) tijekom izvr\u0161avanja dugog zahtjeva. Kao primjer, uzmimo prili\u010dno standardnu sekvencu:<\/p>\n<p><\/p>\n<ol>\n<li>Klijent je poslao zahtjev serveru.<\/li>\n<li>Server je pokrenuo dug proces obrade.<\/li>\n<li>Server je odgovorio klijentu rezultatom.<\/li>\n<\/ol>\n<p><\/p>\n<p>Zamislimo da je u koraku 2 do\u0161lo do prekida veze (ili se mre\u017ea ponovno povezala, ili je korisnik pre\u0161ao na drugu stranicu, prekinuv\u0161i vezu). U tom \u0107e slu\u010daju serveru biti te\u0161ko poslati odgovor korisniku s informacijama o tome \u0161to je konkretno obra\u0111eno. Primjenom CQRS-a, sekvenca \u0107e biti malo druga\u010dija:<\/p>\n<p><\/p>\n<ol>\n<li>Klijent se pretplatio na a\u017euriranja.<\/li>\n<li>Klijent je poslao zahtjev serveru.<\/li>\n<li>Server je odgovorio \"zahtjev primljen\".<\/li>\n<li>Server je odgovorio rezultatom putem kanala iz to\u010dke \"1\".<\/li>\n<\/ol>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Prakti\u010dni arhitektonski obrasci\" src=\"\/wp-content\/uploads\/2020\/05\/8a00ea93eecc7cc0754122857c5f90d0.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kao \u0161to se mo\u017ee vidjeti, shema je malo slo\u017eenija. \u0160tovi\u0161e, intuitivni pristup zahtjev-odgovor ovdje nedostaje. Me\u0111utim, kao \u0161to se mo\u017ee vidjeti, prekid veze tijekom obrade zahtjeva ne\u0107e uzrokovati gre\u0161ku. \u0160tovi\u0161e, ako je korisnik zapravo povezan na servis s nekoliko ure\u0111aja (na primjer, s mobilnog telefona i s tableta), mo\u017ee se omogu\u0107iti da odgovor stigne na oba ure\u0111aja.<\/p>\n<p><\/p>\n<p>Ono \u0161to je zanimljivo, kod obrade dolaznih poruka postaje gotovo identi\u010dan (ne 100%) za doga\u0111aje na koje utje\u010de sam klijent, kao i za ostale doga\u0111aje, uklju\u010duju\u0107i one od drugih klijenata.<\/p>\n<p><\/p>\n<p>Me\u0111utim, u stvarnosti dobivamo dodatne prednosti s obzirom na to da se jednosmjerni tok mo\u017ee obraditi u funkcionalnom stilu (koriste\u0107i RX i sli\u010dne). I to je ve\u0107 ozbiljna prednost, jer se u osnovi aplikacija mo\u017ee u\u010diniti potpuno reaktivnom, jo\u0161 s primjenom funkcionalnog pristupa. Za slo\u017eene programe to mo\u017ee zna\u010dajno u\u0161tedjeti resurse za razvoj i podr\u0161ku.<\/p>\n<p><\/p>\n<p>Ako spojimo ovaj pristup s horizontalnim skaliranjem, kao bonus dobivamo mogu\u0107nost slanja zahtjeva na jedan server, a primanja odgovora s drugog. Tako klijent mo\u017ee odabrati najprikladniju uslugu, a sustav unutar nje i dalje mo\u017ee ispravno obraditi doga\u0111aje.<\/p>\n<p><\/p>\n<h1 id=\"event-sourcing\">Event Sourcing<\/h1>\n<p><\/p>\n<p>Kao \u0161to znate, jedna od osnovnih karakteristika distribuiranog sistema je odsutnost zajedni\u010dkog vremena i zajedni\u010dke kriti\u010dne sekcije. Za jedan proces mo\u017eete izvr\u0161iti sinhronizaciju (na istim mutexima), unutar koje ste sigurni da niko drugi ne izvr\u0161ava taj kod. Me\u0111utim, za distribuirani sistem ne\u0161to sli\u010dno je opasno, jer \u0107e to zahtevati dodatne tro\u0161kove, a tako\u0111e \u0107e pokvariti svu \u010dar obrade - svi \u0107e komponenti u svakom slu\u010daju \u010dekati jednog.<\/p>\n<p><\/p>\n<p>Odatle dolazimo do va\u017enog zaklju\u010dka - brzi distribuirani sistem ne mo\u017ee biti sinhronizovan, jer bismo tada smanjili performanse. S druge strane, \u010desto imamo potrebu za odre\u0111enom dosledno\u0161\u0107u komponenti. I za to mo\u017eemo koristiti pristup s <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Eventual_consistency\">eventual consistency<\/a><\/noindex>, gde je garantirano da u odsustvu izmene podataka kroz odre\u0111eni period nakon poslednjeg a\u017euriranja (\"na kraju\") svi zahtevi \u0107e vra\u0107ati poslednju a\u017euriranu vrednost.<\/p>\n<p><\/p>\n<p>Va\u017eno je razumeti da se za klasi\u010dne baze podataka prili\u010dno \u010desto primenjuje <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Consistency_model#Strict_consistency\">stroga doslednost<\/a><\/noindex>, gde svaki \u010dvor poseduje iste informacije (to se \u010desto posti\u017ee u slu\u010daju kada se transakcija smatra postavljenom tek nakon odgovora drugog servera). Postoje neka olak\u0161anja zbog nivoa izolacije, ali su\u0161tina ostaje ista - mo\u017eete \u017eiveti u potpuno doslednom svetu.<\/p>\n<p><\/p>\n<p>Me\u0111utim, vratimo se na prvobitni zadatak. Ako deo sistema mo\u017ee biti izgra\u0111en sa <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Eventual_consistency\">eventual consistency<\/a><\/noindex>, onda se mo\u017ee izraditi slede\u0107a shema.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Prakti\u010dni arhitektonski obrasci\" src=\"\/wp-content\/uploads\/2020\/05\/33c80be6bc33bd897ca9b9e5525f9ae8.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Va\u017ene karakteristike ovog pristupa:<\/p>\n<p><\/p>\n<ul>\n<li>Svaki dolazni zahtev se stavlja u jedan red.<\/li>\n<li>Tijekom obrade zahtjeva, usluga mo\u017ee tako\u0111e stavljati zadatke u druge redove.<\/li>\n<li>Svaki dolazni doga\u0111aj ima identifikator (koji je potreban za deduplikaciju).<\/li>\n<li>Redoslijed ideolo\u0161ki radi po shemi \"samo dodavanje\". Iz njega nije mogu\u0107e ukloniti elemente ili ih premjestiti.<\/li>\n<li>Red radi po FIFO principu (izvini na tautologiji). Ako je potrebno izvr\u0161iti paralelno izvr\u0161avanje, tada bi trebalo u jednoj od faza premestiti objekte u razli\u010dite redove.<\/li>\n<\/ul>\n<p><\/p>\n<p>Podse\u0107am vas da razmatramo slu\u010daj online skladi\u0161tenja datoteka. U ovom slu\u010daju, sistem \u0107e izgledati otprilike ovako:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Prakti\u010dni arhitektonski obrasci\" src=\"\/wp-content\/uploads\/2020\/05\/b95efb29545dcde1db9432d12d00a1b1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Va\u017eno je napomenuti da usluge na dijagramu ne moraju nu\u017eno zna\u010diti zaseban poslu\u017eitelj. \u010cak i proces mo\u017ee biti isti. Ono \u0161to je bitno je da su ideolo\u0161ki ove stvari razdvojene na na\u010din koji omogu\u0107ava lako primjenjivo horizontalno skaliranje.<\/p>\n<p><\/p>\n<p>Za dva korisnika shema \u0107e izgledati ovako (usluge namijenjene razli\u010ditim korisnicima ozna\u010dene su razli\u010ditim bojama):<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Prakti\u010dni arhitektonski obrasci\" src=\"\/wp-content\/uploads\/2020\/05\/4c4aadc8b9dd505c3ad743e69fee4fae.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Prednosti ovakve kombinacije:<\/p>\n<p><\/p>\n<ul>\n<li>Usluge obrade informacija su razdvojene. Redovi su tako\u0111er razdvojeni. Ako trebamo pove\u0107ati propusnost sustava, samo trebamo pokrenuti vi\u0161e usluga na ve\u0107em broju poslu\u017eitelja.<\/li>\n<li>Kada primamo informacije od korisnika, ne moramo \u010dekati potpuno snimanje podataka. Naprotiv, dovoljno je da odgovorimo s \"ok\", a zatim postupno zapo\u010dnemo rad. Pritom red smanjuje vrhove, jer se dodavanje novog objekta odvija brzo, a korisnik ne mora \u010dekati cijeli ciklus.<\/li>\n<li>Za primjer sam dodao uslugu deduplikacije koja poku\u0161ava spojiti iste datoteke. Ako ona dugo radi u 1% slu\u010dajeva, korisnik to prakti\u010dki ne\u0107e primijetiti (vidi gore), \u0161to je veliki plus jer ne zahtijevamo 100% brzinu i pouzdanost.<\/li>\n<\/ul>\n<p><\/p>\n<p>Me\u0111utim, odmah su vidljivi i nedostaci:<\/p>\n<p><\/p>\n<ul>\n<li>Na\u0161 sustav je izgubio strogu dosljednost. To zna\u010di da, na primjer, ako se pretplatimo na razli\u010dite usluge, teoretski mo\u017eemo dobiti razli\u010dito stanje (jer jedan od servisa mo\u017eda ne\u0107e sti\u0107i primiti obavijest iz unutarnjeg reda). Kao drugo, sustav vi\u0161e nema zajedni\u010dko vrijeme. To jest, ne mo\u017eemo, na primjer, sortirati sve doga\u0111aje jednostavno prema vremenu dolaska, jer sati izme\u0111u poslu\u017eitelja mo\u017eda nisu sinkronizirani (vi\u0161e od toga, isto vrijeme na dva poslu\u017eitelja je utopija).<\/li>\n<li>Nikakvi doga\u0111aji se vi\u0161e ne mogu jednostavno poni\u0161titi (kao \u0161to se mo\u017ee u\u010diniti s bazom podataka). Umjesto toga potrebno je dodati novi doga\u0111aj \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/stackoverflow.com\/questions\/49451237\/compensating-events-on-cqrs-es-architecture\">kompenzacijski doga\u0111aj<\/a><\/noindex>, koji \u0107e promijeniti posljednje stanje u potrebno. Kao primjer iz sli\u010dnog podru\u010dja: bez prepisivanja povijesti (\u0161to je lo\u0161e u nekim slu\u010dajevima) u gitu ne mo\u017ee se poni\u0161titi commit, ali se mo\u017ee napraviti posebni <noindex><a rel=\"nofollow\" href=\"https:\/\/git-scm.com\/docs\/git-revert\">rollback commit<\/a><\/noindex>, koji \u0107e u su\u0161tini jednostavno vratiti staro stanje. Me\u0111utim, u povijesti \u0107e ostati i pogre\u0161ni commit i rollback.<\/li>\n<li>Shema podataka mo\u017ee se mijenjati od izdanja do izdanja, no stari doga\u0111aji sada se ne mogu a\u017eurirati na novi standard (jer se doga\u0111aji u na\u010delu ne mogu mijenjati).<\/li>\n<\/ul>\n<p><\/p>\n<p>Kao \u0161to se mo\u017ee vidjeti, Event Sourcing se odli\u010dno uklapa s CQRS-om. \u0160tovi\u0161e, implementacija sustava s u\u010dinkovitim i prakti\u010dnim redovima, ali bez odvajanja tokova podataka, sama po sebi je te\u0161ka, jer \u0107e morati dodavati to\u010dke sinkronizacije koje \u0107e neutralizirati cijeli pozitivan u\u010dinak redova. Primjenom oba pristupa istovremeno, potrebno je neznatno prilagoditi kod rada programa. U na\u0161em slu\u010daju, prilikom slanja datoteke na server, u odgovoru dolazi samo \"ok\", \u0161to zna\u010di da je \"operacija dodavanja datoteke spremljena\". Formalno, to ne zna\u010di da su podaci ve\u0107 dostupni na drugim ure\u0111ajima (na primjer, usluga deduplikacije mo\u017ee rekonstrukcijom rekonstruirati indeks). Me\u0111utim, nakon nekog vremena klijent \u0107e primiti obavijest u stilu \"datoteka X spremljena\".<\/p>\n<p><\/p>\n<p>Kao rezultat:<\/p>\n<p><\/p>\n<ul>\n<li>Broj statusa slanja datoteka se pove\u0107ava: umjesto klasi\u010dnog \"datoteka poslana\" dobivamo dva: \"datoteka dodana u red na serveru\" i \"datoteka spremljena u skladi\u0161tu\". Potonje zna\u010di da drugi ure\u0111aji ve\u0107 mogu po\u010deti primati datoteku (s napomenom da redovi rade razli\u010ditom brzinom).<\/li>\n<li>Zbog toga \u0161to informacije o slanju sada dolaze putem razli\u010ditih kanala, moramo smisliti rje\u0161enja za dobivanje statusa obrade datoteke. Kao posljedica toga: za razliku od klasi\u010dnog request-response modela, klijent mo\u017ee biti ponovno pokrenut tijekom obrade datoteke, a status same obrade \u0107e biti to\u010dan. Ovaj aspekt funkcioni\u0161e, u su\u0161tini, iz kutije. Kao posljedica: sada smo tolerantniji na gre\u0161ke.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"sharding\">Sharding<\/h1>\n<p><\/p>\n<p>Kao \u0161to je ve\u0107 opisano, u sustavima s event sourcingom nema stroge dosljednosti. To zna\u010di da mo\u017eemo koristiti vi\u0161e skladi\u0161ta bez ikakve sinkronizacije me\u0111u njima. Pribli\u017eavaju\u0107i se na\u0161em zadatku, mo\u017eemo:<\/p>\n<p><\/p>\n<ul>\n<li>Dijeliti datoteke po vrstama. Na primjer, slike\/videozapis mo\u017eemo dekodirati i odabrati u\u010dinkovitiji format.<\/li>\n<li>Razdvojite ra\u010dune prema dr\u017eavama. Zbog mnogih zakona, ovakva mogu\u0107nost mo\u017ee biti potrebna, no ova arhitektura omogu\u0107uje automatsko ostvarenje te opcije.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Prakti\u010dni arhitektonski obrasci\" src=\"\/wp-content\/uploads\/2020\/05\/dd310df700bc39c014d0105a3425fece.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ako \u017eelite prebaciti podatke iz jedne pohrane u drugu, standardna sredstva ne\u0107e biti dovoljna. Na\u017ealost, u tom slu\u010daju morate zaustaviti red, izvr\u0161iti migraciju, a zatim ga ponovno pokrenuti. Op\u0107enito, podaci se ne mogu prebaciti 'u hodu', me\u0111utim, ako se red doga\u0111aja potpuno pohranjuje i imate snimke prethodnih stanja pohrane, mo\u017eemo ponovno reproducirati doga\u0111aje na sljede\u0107i na\u010din:<\/p>\n<p><\/p>\n<ul>\n<li>U Event Source svaki doga\u0111aj ima svoj identifikator (idealno \u2014 ne smanjuju\u0107i se). To zna\u010di da mo\u017eemo dodati polje u pohranu \u2014 id posljednjeg obra\u0111enog elementa.<\/li>\n<li>Dubliciramo red kako bi se svi doga\u0111aji mogli obra\u0111ivati za nekoliko neovisnih pohrana (prvi je onaj u kojem se trenutno pohranjuju podaci, a drugi je novi, koji je trenutno prazan). Drugi red, naravno, jo\u0161 nije obra\u0111en.<\/li>\n<li>Pokre\u0107emo drugi red (tj. po\u010dinjemo s ponovnim reprodukcijom doga\u0111aja).<\/li>\n<li>Kada novi red postane relativno prazan (tj. prosje\u010dna razlika u vremenu izme\u0111u dodavanja elementa i njegovog va\u0111enja bude prihvatljiva), mo\u017eemo po\u010deti prebacivati \u010ditatelje na novu pohranu.<\/li>\n<\/ul>\n<p><\/p>\n<p>Kao \u0161to se mo\u017ee vidjeti, u na\u0161em sustavu nije bilo i nema stroge dosljednosti. Postoji samo eventualna dosljednost, \u0161to zna\u010di jamstvo da se doga\u0111aji obra\u0111uju u istom redoslijedu (me\u0111utim, mogu\u0107e je s razli\u010ditim odgodama). Koriste\u0107i to, mo\u017eemo relativno lako prenijeti podatke bez zaustavljanja sustava na drugu stranu svijeta.<\/p>\n<p><\/p>\n<p>Tako, nastavljaju\u0107i na\u0161 primjer o online pohrani za datoteke, ova arhitektura nam ve\u0107 donosi niz prednosti:<\/p>\n<p><\/p>\n<ul>\n<li>Mo\u017eemo premje\u0161tati objekte bli\u017ee korisnicima, na dinami\u010dan na\u010din. Time mo\u017eemo pobolj\u0161ati kvalitetu usluge. <\/li>\n<li>Mo\u017eemo pohraniti dio podataka unutar kompanija. Na primjer, Enterprise korisnici \u010desto zahtijevaju pohranu svojih podataka u kontroliranim podatkovnim centrima (kako bi se izbjegla curenja podataka). Kroz sharding, mo\u017eemo lako podr\u017eati ovu opciju. A zadatak je jo\u0161 jednostavniji ako klijent ima kompatibilnu obla\u010dnu infrastrukturu (na primjer, <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.microsoft.com\/en-gb\/azure-stack\/asdk\/asdk-what-is?view=azs-1910\">Azure self hosted<\/a><\/noindex>).<\/li>\n<li>A najva\u017enije je da to ne moramo raditi. Za po\u010detak, sasvim bi nam odgovaralo jedno skladi\u0161te za sve ra\u010dune (kako bismo br\u017ee po\u010deli raditi). Klju\u010dna karakteristika ovog sustava je da, iako je pro\u0161iriv, u po\u010detnoj fazi je dovoljno jednostavan. Jednostavno ne trebate odmah pisati kod koji radi s milijun odvojenih neovisnih redova itd. Ako zatreba, to se mo\u017ee u\u010diniti u budu\u0107nosti.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"static-content-hosting\">Hosting stati\u010dkog sadr\u017eaja<\/h1>\n<p><\/p>\n<p>Ova to\u010dka mo\u017ee se \u010diniti potpuno o\u010ditom, ali je svejedno potrebna za vi\u0161e-manje standardnu optere\u0107enu aplikaciju. Njegova su\u0161tina je jednostavna: sav stati\u010dki sadr\u017eaj ne distribuira se s istog poslu\u017eitelja na kojem se nalazi aplikacija, ve\u0107 s posebnih poslu\u017eitelja, namijenjenih isklju\u010divo za tu svrhu. Kao rezultat, ove operacije se izvode br\u017ee (hipotetski, nginx isporu\u010duje datoteke br\u017ee i uz manje tro\u0161kove od Java poslu\u017eitelja). Osim toga, arhitektura CDN (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Content_delivery_network\">Mre\u017ea za isporuku sadr\u017eaja<\/a><\/noindex>) omogu\u0107ava nam da smjestimo na\u0161e datoteke bli\u017ee krajnjim korisnicima, \u0161to pozitivno utje\u010de na upotrebljivost usluge.<\/p>\n<p><\/p>\n<p>Najjednostavniji i standardni primjer stati\u010dkog sadr\u017eaja je skup skripti i slika za web stranicu. S njima je sve jednostavno \u2014 poznate su unaprijed, zatim se arhiva u\u010ditava na CDN poslu\u017eitelje, odakle se distribuiraju krajnjim korisnicima.<\/p>\n<p><\/p>\n<p>Me\u0111utim, u praksi se za stati\u010dki sadr\u017eaj mo\u017ee primijeniti pristup sli\u010dan lambda arhitekturi. Vratimo se na\u0161em zadatku (online skladi\u0161te datoteka) u kojem trebamo isporu\u010divati datoteke korisnicima. Najjednostavnije rje\u0161enje je izraditi uslugu koja za svaki korisni\u010dki zahtjev izvr\u0161ava sve potrebne provjere (autentifikacija itd.), a zatim preuzima datoteku izravno iz na\u0161eg skladi\u0161ta. Glavni nedostatak ovog pristupa je to \u0161to se stati\u010dki sadr\u017eaj (a datoteka s odre\u0111enom revizijom, u su\u0161tini, jest stati\u010dki sadr\u017eaj) isporu\u010duje s istog poslu\u017eitelja koji sadr\u017ei poslovnu logiku. Umjesto toga, mogu\u0107e je stvoriti sljede\u0107u shemu:<\/p>\n<p><\/p>\n<ul>\n<li>Poslu\u017eitelj generira URL za preuzimanje. Mo\u017ee biti u obliku file_id + key, gdje je key mini-digitalni potpis koji daje pravo na pristup resursu sljede\u0107a 24 sata.<\/li>\n<li>Isporuku datoteke obavlja jednostavan nginx s sljede\u0107im opcijama:\n<ul>\n<li>Ke\u0161iranje sadr\u017eaja. Budu\u0107i da ova usluga mo\u017ee biti na zasebnom serveru, ostavili smo prostor za budu\u0107nost s mogu\u0107no\u0161\u0107u pohrane svih posljednjih preuzetih datoteka na disku.<\/li>\n<li>Provjera klju\u010da u trenutku uspostavljanja veze<\/li>\n<\/ul>\n<\/li>\n<li>Opcionalno: streaming sadr\u017eaja. Na primjer, ako komprimiramo sve datoteke u servisu, mogu\u0107e je izvr\u0161iti dekompresiju direktno u ovom modulu. Kao posljedica: IO operacije se obavljaju tamo gdje im je mjesto. Arhivator napisan u Javi lako mo\u017ee zauzeti puno dodatne memorije, no prepisivanje servisa s poslovnom logikom na uvjetni Rust\/C++ mo\u017ee se tako\u0111er pokazati neu\u010dinkovitim. U na\u0161em slu\u010daju koristimo razli\u010dite procese (ili \u010dak servise), pa mo\u017eemo prili\u010dno u\u010dinkovito odvojiti poslovnu logiku i IO operacije.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Prakti\u010dni arhitektonski obrasci\" src=\"\/wp-content\/uploads\/2020\/05\/4dead07d5824938e09b986192ccc8f5e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Sli\u010dna shema ne izgleda kao raspodjela stati\u010dkog sadr\u017eaja (budu\u0107i da ne prebacujemo cijeli paket stati\u010dkih datoteka negdje), me\u0111utim u stvarnosti ovaj pristup se upravo bavi raspodjelom nepromjenjivih podataka. \u0160tovi\u0161e, ovu shemu mo\u017eemo generalizirati i na druge slu\u010dajeve kada sadr\u017eaj nije samo stati\u010dan, ve\u0107 se mo\u017ee predstaviti kao skup nepromjenjivih i neizbrisivih blokova (iako se mogu dodavati).<\/p>\n<p><\/p>\n<p>Kao jo\u0161 jedan primjer (za u\u010dvr\u0161\u0107ivanje): ako ste radili s Jenkinsom\/TeamCityjem, znate da su oba rje\u0161enja napisana na Javi. Oba predstavljaju Java proces koji se bavi orkestracijom gradnji, kao i upravljanjem sadr\u017eajem. Konkretno, oba imaju zadatke poput \"predati datoteku\/mapu s poslu\u017eitelja\". Na primjer: isporuka artefakata, prijenos izvornog koda (kada agent ne preuzima kod izravno iz repozitorija, nego to \u010dini poslu\u017eitelj), pristup logovima. Svi ti zadaci se razlikuju po optere\u0107enju na IO. Dakle, ispostavlja se da poslu\u017eitelj, koji je odgovoran za slo\u017eenu poslovnu logiku, tako\u0111er mora u\u010dinkovito probijati velike koli\u010dine podataka. A \u0161to je najzanimljivije, takvu operaciju je mogu\u0107e delegirati istom nginx-u prema to\u010dno istoj shemi (samo je potrebno dodati klju\u010d podataka u zahtjev).<\/p>\n<p><\/p>\n<p>Me\u0111utim, ako se vratimo na\u0161oj sustavu, dobijamo sli\u010dnu shemu:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Prakti\u010dni arhitektonski obrasci\" src=\"\/wp-content\/uploads\/2020\/05\/97cfbf5daaa6678a9eecc3169692f0fc.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Kao \u0161to se mo\u017ee vidjeti, sustav je radikalno zakomplikan. Sada to nije samo mini-proces koji pohranjuje datoteke lokalno. Sada su potrebni i kompleksnija podr\u0161ka, upravljanje verzijama API-a itd. Stoga, nakon \u0161to su sve dijagrame nacrtane, najbolje je detaljno procijeniti isplati li se sli\u010dna pro\u0161irivost. No, ako \u017eelite imati mogu\u0107nost pro\u0161irivanja sustava (uklju\u010duju\u0107i i rad s ve\u0107im brojem korisnika), morat \u0107ete se odlu\u010diti za sli\u010dna rje\u0161enja. Kao rezultat, arhitektura sustava je spremna za pove\u0107anje optere\u0107enja (prakti\u010dki, svaki komponent mo\u017ee se klonirati za horizontalno skaliranje). Sustav se mo\u017ee a\u017eurirati bez njegovog zaustavljanja (samo \u0107e neke operacije neznatno usporiti).<\/p>\n<p><\/p>\n<p>Kao \u0161to sam ve\u0107 rekao na po\u010detku, sada niz internetskih usluga do\u017eivljava pove\u0107ano optere\u0107enje. A neke od njih jednostavno prestaju ispravno raditi. U su\u0161tini, sustavi su otkazali to\u010dno u trenutku kada bi posao trebao donositi novac. To zna\u010di da umjesto odgo\u0111ene isporuke, umjesto ponude klijentima da 'planiraju isporuke za sljede\u0107ih nekoliko mjeseci', sustav jednostavno ka\u017ee 'idite konkurentima'. Uvijeno, to je cijena niske performanse: gubici \u0107e se dogoditi upravo kada bi profit bio najvi\u0161i.<\/p>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Zaklju\u010dak<\/h1>\n<p><\/p>\n<p>Svi ti pristupi bili su poznati i ranije. Isti VK ve\u0107 dugo koristi ideju Static Content Hosting za isporuku slika. Mno\u0161tvo online igara koristi sharding shemu za razdvajanje igra\u010da po regijama ili za razdvajanje igra\u010dkih lokacija (ako je svijet jedinstven). Event sourcing pristup aktivno se koristi u elektroni\u010dkoj po\u0161ti. Ve\u0107ina aplikacija za trgovce, gdje kontinuirano dolaze podaci, zapravo je izgra\u0111ena na CQRS pristupu, kako bi se mogla filtrirati primljeni podaci. Pa, horizontalno skaliranje ve\u0107 dugo se primjenjuje u mnogim uslugama.<\/p>\n<p><\/p>\n<p>Me\u0111utim, ono \u0161to je najva\u017enije, svi ovi obrasci postali su vrlo lako primjenjivi u modernim aplikacijama (ako su naravno primjereni). Oblaci nude Sharding i horizontalno skaliranje odmah, \u0161to je puno lak\u0161e nego naru\u010divanje razli\u010ditih namjenskih poslu\u017eitelja u razli\u010ditim podatkovnim centrima ru\u010dno. CQRS je postao mnogo lak\u0161i, barem zbog razvoja knji\u017enica kao \u0161to je RX. Prije 10 godina rijetka web stranica mogla bi podr\u017eati takvo \u0161to. Event Sourcing tako\u0111er se configure veoma lako zahvaljuju\u0107i ve\u0107 gotovim kontejnerima s Apache Kafka. Prije 10 godina to bi bila inovacija, sada je to svakodnevica. Sli\u010dno vrijedi i za Static Content Hosting: zbog prakti\u010dnijih tehnologija (uklju\u010duju\u0107i i to \u0161to postoji detaljna dokumentacija i velika baza odgovora), sli\u010dan pristup postao je jo\u0161 jednostavniji.<\/p>\n<p><\/p>\n<p>Kao rezultat, implementacija niza prili\u010dno slo\u017eenih arhitektonskih obrazaca sada je mnogo jednostavnija, \u0161to zna\u010di da ih treba bolje unaprijed prou\u010diti. Ako je u desetogodi\u0161njoj aplikaciji odba\u010deno jedno od rje\u0161enja iznad zbog visoke cijene implementacije i odr\u017eavanja, sada, u novoj aplikaciji, ili nakon refaktoringa, mogu\u0107e je napraviti uslugu koja \u0107e arhitektonski ve\u0107 biti i pro\u0161iriva (s aspekta performansi), i spremna za nove zahtjeve klijenata (npr. za lokalizaciju osobnih podataka).<\/p>\n<p><\/p>\n<p>I najva\u017enije: molimo vas, nemojte koristiti ove pristupe ako imate jednostavnu aplikaciju. Da, oni su lijepi i zanimljivi, me\u0111utim za stranicu s maksimalnim posjetom od 100 ljudi \u010desto se mo\u017ee zadovoljiti klasi\u010dnim monolitom (barem izvana, iznutra se sve mo\u017ee podijeliti na module itd.).<\/p>\n<p>Izvor: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/dbtc\/blog\/499758\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0412 \u0441\u0432\u0435\u0442\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438\u0437-\u0437\u0430 \u043a\u043e\u0440\u043e\u043d\u0430\u0432\u0438\u0440\u0443\u0441\u0430 \u0440\u044f\u0434 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0442\u0430\u043b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u0434\u043d\u0430 \u0438\u0437 \u0442\u043e\u0440\u0433\u043e\u0432\u044b\u0445 \u0441\u0435\u0442\u0435\u0439 \u0432 \u0412\u0435\u043b\u0438\u043a\u043e\u0431\u0440\u0438\u0442\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0430 \u0441\u0430\u0439\u0442 \u0441 \u043e\u043d\u043b\u0430\u0439\u043d-\u0437\u0430\u043a\u0430\u0437\u0430\u043c\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0435 \u0445\u0432\u0430\u0442\u0438\u043b\u043e \u043c\u043e\u0449\u043d\u043e\u0441\u0442\u0435\u0439. \u0418 \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440, \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0431\u043e\u043b\u0435\u0435 \u043c\u043e\u0449\u043d\u043e\u0435 \u043e\u0431\u043e\u0440\u0443\u0434\u043e\u0432\u0430\u043d\u0438\u0435, \u043e\u0434\u043d\u0430\u043a\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430\u0434\u043e (\u0438\u043b\u0438 \u043e\u043d\u0438 \u0443\u0439\u0434\u0443\u0442 \u043a \u043a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u0430\u043c). \u0412 \u044d\u0442\u043e\u0439 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":80036,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-80035","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=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0412 \u0441\u0432\u0435\u0442\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438\u0437-\u0437\u0430 \u043a\u043e\u0440\u043e\u043d\u0430\u0432\u0438\u0440\u0443\u0441\u0430 \u0440\u044f\u0434 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0442\u0430\u043b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443.\" \/>\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\/hr\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.4\" \/>\n\t\t<meta property=\"og:locale\" content=\"hr_HR\" \/>\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\u0423\u0434\u043e\u0431\u043d\u044b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0412 \u0441\u0432\u0435\u0442\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438\u0437-\u0437\u0430 \u043a\u043e\u0440\u043e\u043d\u0430\u0432\u0438\u0440\u0443\u0441\u0430 \u0440\u044f\u0434 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0442\u0430\u043b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny\" \/>\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=\"2020-05-02T11:42:54+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-05-02T11:42:54+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\udd47Prakti\u010dni arhitektonski obrasci | ProHoster","description":"Pozdrav, Habr! U svjetlu trenutnih doga\u0111aja uslijed koronavirusa, niz internetskih usluga po\u010deo je primati pove\u0107ano optere\u0107enje.","canonical_url":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"hr_HR","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\u0423\u0434\u043e\u0431\u043d\u044b\u0435 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u044b\u0435 \u043f\u0430\u0442\u0442\u0435\u0440\u043d\u044b | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u0412 \u0441\u0432\u0435\u0442\u0435 \u0442\u0435\u043a\u0443\u0449\u0438\u0445 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438\u0437-\u0437\u0430 \u043a\u043e\u0440\u043e\u043d\u0430\u0432\u0438\u0440\u0443\u0441\u0430 \u0440\u044f\u0434 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442-\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0441\u0442\u0430\u043b \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0443\u0432\u0435\u043b\u0438\u0447\u0435\u043d\u043d\u0443\u044e \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0443.","og:url":"https:\/\/prohoster.info\/hr\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny","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":"2020-05-02T11:42:54+00:00","article:modified_time":"2020-05-02T11:42:54+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"80035","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":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 16:26:40","updated":"2022-09-28 01:38:29","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/80035","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/comments?post=80035"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/posts\/80035\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media\/80036"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/media?parent=80035"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/categories?post=80035"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hr\/wp-json\/wp\/v2\/tags?post=80035"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}