{"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\/sl\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny","title":{"rendered":"Prakti\u010dni arhitektonski obrasci","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hello, Habr!<\/p>\n<p><\/p>\n<p>V lu\u010di trenutnih dogodkov zaradi koronavirusa so nekateri internetni servisi za\u010deli prejemati pove\u010dano obremenitev. Na primer, <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\">eno od trgovskih omre\u017eij v Zdru\u017eenem kraljestvu je preprosto ustavilo spletno mesto za naro\u010danje<\/a><\/noindex>, ker ni bilo dovolj mo\u010di. In dale\u010d ne vedno je mogo\u010de izbolj\u0161ati stre\u017enik, preprosto dodajanje zmogljivej\u0161e opreme, vendar moramo obdelati zahteve strank (ali pa odidejo k konkurentom).<\/p>\n<p><\/p>\n<p>V tem \u010dlanku bom na kratko opisal priljubljene prakse, ki bodo omogo\u010dile hitro in zanesljivo storitev. Izmed mo\u017enih razvoja sem izbral le tiste, ki jih lahko zdaj <strong>enostavno uporabite<\/strong>. Za vsako to\u010dko imate ali \u017ee pripravljene knji\u017enice, ali pa je mogo\u010de nalogo re\u0161iti s pomo\u010djo 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>Najpreprostej\u0161a in vsem znana to\u010dka. Pogojujemo, da sta najbolj pogosto uporabljeni dve shemi porazdelitve obremenitve \u2014 horizontalno in 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\">V prvem primeru<\/a><\/noindex> dovolite storitvam, da delujejo vzporedno, s \u010dimer porazdelite obremenitev med njimi. <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\">V drugem<\/a><\/noindex> naro\u010dite mo\u010dnej\u0161e stre\u017enike ali optimizirate kodo.<\/p>\n<p><\/p>\n<p>Kot primer bom vzel abstraktno obla\u010dno shrambo datotek, tj. nekak\u0161en analog OwnCloud, OneDrive in tako dalje.<\/p>\n<p><\/p>\n<p>Standardna slika tak\u0161ne sheme je spodaj, vendar le predstavlja kompleksnost sistema. Kaj pa, \u010de uporabnik shrani datoteko iz tablice in jo nato \u017eeli pogledati na telefonu?<\/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 med pristopi: pri vertikalnem skaliranju smo pripravljeni pove\u010dati mo\u010d enot, pri horizontalnem pa dodajamo nove enote, da porazdelimo obremenitev.<\/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\">Lo\u010devanje odgovornosti po ukazu in poizvedbi<\/a><\/noindex> je precej pomemben vzorec, saj omogo\u010da razli\u010dnim strankam, ne le, da se pove\u017eejo z razli\u010dnimi storitvami, ampak tudi prejemajo enake tokove dogodkov. Njegove prednosti niso tako o\u010ditne za preprosto aplikacijo, vendar je izjemno pomemben (in preprost) za obremenjeno storitev. Njegovo bistvo je: vhodni in izhodni tokovi podatkov se ne smejo kri\u017eati. To pomeni, da ne morete poslati poizvedbe in pri\u010dakovati odgovora, temve\u010d po\u0161ljete poizvedbo v storitev A, vendar odgovor prejmete v storitvi B.<\/p>\n<p><\/p>\n<p>Prvi bonus ovog pristupa je mogu\u0107nost prekida veze (u \u0161irokom smislu te re\u010di) tokom izvr\u0161avanja dugog zahteva. Na primer, uzmimo vi\u0161e-manje standardnu sekvencu:<\/p>\n<p><\/p>\n<ol>\n<li>Klijent je poslao zahtev serveru.<\/li>\n<li>Server je pokrenuo dugu obradu.<\/li>\n<li>Server je odgovorio klijentu rezultatom.<\/li>\n<\/ol>\n<p><\/p>\n<p>Zamislimo da se u koraku 2 dogodio prekid veze (ili se mre\u017ea ponovo povezala, ili je korisnik pre\u0161ao na drugu stranicu, prekinuv\u0161i vezu). U tom slu\u010daju, serveru \u0107e biti te\u0161ko da po\u0161alje odgovor korisniku s informacijama o tome \u0161ta je ta\u010dno obra\u0111eno. Primenom CQRS, 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 zahtev serveru.<\/li>\n<li>Server je odgovorio \"zahtev prihva\u0107en\".<\/li>\n<li>Server je odgovorio rezultatom preko kanala iz ta\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 videti, shema je malo slo\u017eenija. \u0160tavi\u0161e, intuitivni pristup zahteva-odgovora ovde nedostaje. Me\u0111utim, kao \u0161to se vidi, prekid veze tokom obrade zahteva ne\u0107e dovesti do gre\u0161ke. \u0160tavi\u0161e, ako je korisnik zapravo povezan sa servisom s vi\u0161e ure\u0111aja (na primer, sa mobilnog telefona i sa tableta), mo\u017ee se omogu\u0107iti da odgovor dolazi na oba ure\u0111aja.<\/p>\n<p><\/p>\n<p>Zanimljivo je da kod obrade dolaznih poruka postaje sli\u010dan (ne 100%) za doga\u0111aje na koje je uticao 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 dobijamo dodatne pogodnosti zbog toga \u0161to se jednosmerni protok mo\u017ee obra\u0111ivati u funkcionalnom stilu (koriste\u0107i RX i sli\u010dne alate). I ovo je ozbiljna prednost, jer se u su\u0161tini aplikacija mo\u017ee u\u010diniti potpuno reaktivnom, uz primenu funkcionalnog pristupa. Za kompleksne programe to mo\u017ee zna\u010dajno u\u0161tedeti resurse na razvoju i odr\u017eavanju.<\/p>\n<p><\/p>\n<p>Ako spojimo ovaj pristup s horizontalnim skaliranjem, dobijamo mogu\u0107nost slanja zahteva na jedan server, a primanja odgovora od drugog. Tako klijent mo\u017ee sam izabrati uslugu koja mu odgovara, a sistem unutar mo\u017ee ispravno obraditi doga\u0111aje.<\/p>\n<p><\/p>\n<h1 id=\"event-sourcing\">Event Sourcing<\/h1>\n<p><\/p>\n<p>Kot veste, ena od osnovnih zna\u010dilnosti porazdeljenega sistema je pomanjkanje skupnega \u010dasa in skupne kriti\u010dne sekcije. Za en proces lahko izvedete sinhronizacijo (na istih mutexih), znotraj katere ste prepri\u010dani, da nih\u010de drug ne izvaja te kode. Vendar pa je to za porazdeljen sistem nevarno, saj bo to zahtevalo prevelike stro\u0161ke, hkrati pa bi uni\u010dilo vso \u010darobnost skaliranja \u2014 vse komponente bi se kljub temu morale zana\u0161ati na eno samo.<\/p>\n<p><\/p>\n<p>Od tod pridemo do pomembnega dejstva \u2014 hitrega porazdeljenega sistema ni mogo\u010de sinhronizirati, saj bi s tem zmanj\u0161ali u\u010dinkovitost. Po drugi strani pa pogosto potrebujemo dolo\u010deno usklajenost komponent. In za to lahko uporabimo pristop z <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Eventual_consistency\">eventual consistency<\/a><\/noindex>, kjer je zagotovljeno, da v odsotnosti sprememb podatkov po nekem \u010dasovnem obdobju po zadnji posodobitvi (\u201ena koncu\u201c) vsi zahtevki vrnejo zadnjo posodobljeno vrednost.<\/p>\n<p><\/p>\n<p>Pomembno je razumeti, da se za klasi\u010dne baze podatkov pogosto uporablja <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Consistency_model#Strict_consistency\">stroga usklajenost<\/a><\/noindex>, kjer vsak vozli\u0161\u010de obvladuje enake informacije (to se pogosto dose\u017ee, ko se transakcija \u0161teje za dokon\u010dano \u0161ele po odgovoru drugega stre\u017enika). Tukaj so nekatera popustitev zaradi stopenj izolacije, vendar osnovna ideja ostaja enaka \u2014 lahko \u017eivite v popolnoma usklajenem svetu.<\/p>\n<p><\/p>\n<p>Vendar se vrnimo k prvotni nalogi. \u010ce je del sistema mogo\u010de zgraditi s <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Eventual_consistency\">eventual consistency<\/a><\/noindex>, potem lahko zgradimo naslednjo shemo.<\/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>Pomembne zna\u010dilnosti tega pristopa:<\/p>\n<p><\/p>\n<ul>\n<li>Vsak prihajajo\u010di zahtevek se postavi v eno vrsto.<\/li>\n<li>Med obdelavo zahtevka lahko storitev prav tako postavi naloge v druge vrste.<\/li>\n<li>Vsak prihajajo\u010di dogodek ima identifikator (ki je potreben za deduplikacijo).<\/li>\n<li>Vrsta deluje ideolo\u0161ko po na\u010delu \"samo dodajanje\". Iz nje ni mogo\u010de odstranjevati elementov ali jih prestavljati.<\/li>\n<li>Vrsta deluje po shemi FIFO (oprosti za pleonazem). \u010ce je potrebno izvesti vzporedno izvajanje, je treba v eni izmed faz premakniti objekte v razli\u010dne vrste.<\/li>\n<\/ul>\n<p><\/p>\n<p>Spomnim vas, da obravnavamo primer spletnega shranjevanja datotek. V tem primeru bo sistem izgledal nekako takole:<\/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>Pomembno je, da storitve na diagramu ne pomenijo nujno lo\u010denega stre\u017enika. Tudi postopek je lahko enak. Pomembnej\u0161e je, da so te stvari ideolo\u0161ko razdeljene na na\u010din, da je mogo\u010de enostavno uporabiti horizontalno skaliranje.<\/p>\n<p><\/p>\n<p>Za dva uporabnika bo shema videti tako (storitev, namenjene razli\u010dnim uporabnikom, so ozna\u010dene z razli\u010dnimi barvami):<\/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>Bonusi tak\u0161ne kombinacije:<\/p>\n<p><\/p>\n<ul>\n<li>Storitve za obdelavo informacij so razdeljene. \u010cakalne vrste so prav tako razdeljene. \u010ce bomo potrebovali pove\u010dati prepustnost sistema, bomo le morali zagnati ve\u010d storitev na ve\u010djem \u0161tevilu stre\u017enikov.<\/li>\n<li>Ko od uporabnika pridobimo informacije, nam ni treba \u010dakati na popolno shranjevanje podatkov. Nasprotno, zadostuje, da odgovorimo \u00bbv redu\u00ab, nato pa postopoma za\u010dnemo delati. Hkrati \u010dakalna vrsta omili vrhove, saj se dodajanje novega objekta zgodi hitro, polnega procesa skozi celoten cikel pa uporabnik ne rabi \u010dakati.<\/li>\n<li>Za primer sem dodal storitev deduplifikacije, ki posku\u0161a zdru\u017eiti enake datoteke. \u010ce traja dolgo pri 1 % primerov, tega stranka prakti\u010dno ne bo opazila (glej zgoraj), kar je velika prednost, saj od nas ni ve\u010d zahtevana 100-odstotna hitrost in zanesljivost.<\/li>\n<\/ul>\n<p><\/p>\n<p>Vendar se takoj vidijo tudi slabosti:<\/p>\n<p><\/p>\n<ul>\n<li>Na\u0161emu sistemu je zmanjkalo stroge usklajenosti. To pomeni, da lahko, \u010de se na primer naro\u010dimo na razli\u010dne storitve, teoreti\u010dno pridobimo razli\u010dno stanje (saj lahko ena od storitev ne uspe pravo\u010dasno sprejeti obvestila iz notranje \u010dakalne vrste). Kot \u0161e en posledica, sistem zdaj nima skupnega \u010dasa. To pomeni, da ni mogo\u010de na primer razvrstiti vseh dogodkov preprosto po \u010dasu prihoda, saj ure med stre\u017eniki morda niso sinhronizirane (poleg tega enaka ura na dveh stre\u017enikih predstavlja utopijo).<\/li>\n<li>Nobenih dogodkov zdaj ni mogo\u010de preprosto razveljaviti (kot bi to lahko storili z bazo podatkov). Namesto tega je potrebno dodati nov dogodek \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/stackoverflow.com\/questions\/49451237\/compensating-events-on-cqrs-es-architecture\">compensation event<\/a><\/noindex>, ki bo spremenil zadnje stanje v potrebno. Kot primer iz sorodne podro\u010dja: brez prepisovanja zgodovine (kar je v nekaterih primerih slabo) v gitu ni mogo\u010de razveljaviti commit, vendar pa je mogo\u010de narediti posebni <noindex><a rel=\"nofollow\" href=\"https:\/\/git-scm.com\/docs\/git-revert\">rollback commit<\/a><\/noindex>, ki po svoji naravi preprosto vrne staro stanje. Vendar pa bo v zgodovini ostal tako napa\u010den commit kot tudi rollback.<\/li>\n<li>Podatkovna shema se lahko spreminja z vsakim izidom, vendar starih dogodkov ni mogo\u010de nadgraditi na nov standard (ker dogodkov v osnovi ni mogo\u010de spreminjati).<\/li>\n<\/ul>\n<p><\/p>\n<p>Kot je razvidno, se Event Sourcing odli\u010dno ujema s CQRS. \u0160e ve\u010d, implementirati sistem z u\u010dinkovitim in uporabnikom prijaznim \u010dakanjem, vendar brez lo\u010devanja podatkovnih tokov, je \u017ee samo po sebi zahtevno, saj je potrebno dodati to\u010dke sinhronizacije, ki bi izni\u010dile celoten pozitivni u\u010dinek \u010dakanja. Ko uporabljamo oba pristopa hkrati, je potrebna manj\u0161a korekcija v kodi programa. V na\u0161em primeru, ko je datoteka poslana na stre\u017enik, se odziv vrne samo z \u00abok\u00bb, kar pomeni le to, da je \u00aboperacija dodajanja datoteke shranjena\u00bb. Formalno to ne pomeni, da so podatki \u017ee dostopni na drugih napravah (na primer, storitev deduplikacije lahko preoblikuje indeks). Vendar pa bo po dolo\u010denem \u010dasu stranki pri\u0161lo obvestilo v slogu \u00abdatoteka X je shranjena\u00bb.<\/p>\n<p><\/p>\n<p>Kot rezultat:<\/p>\n<p><\/p>\n<ul>\n<li>\u0160tevilo statusov za po\u0161iljanje datotek se pove\u010duje: namesto klasi\u010dnega \u00abdatoteka je bila poslana\u00bb prejmete dva: \u00abdatoteka je bila dodana v \u010dakalno vrsto na stre\u017eniku\u00bb in \u00abdatoteka je shranjena v shrambo\u00bb. Zadnje pomeni, da lahko druge naprave za\u010dnejo prejemati datoteko (z upo\u0161tevanjem, da \u010dakalne vrste delujejo z razli\u010dnimi hitrostmi).<\/li>\n<li>Zaradi tega, ker informacije o po\u0161iljanju zdaj prihajajo po razli\u010dnih kanalih, moramo razviti re\u0161itve, da pridobimo status obdelave datoteke. Kot posledica tega: v nasprotju s klasi\u010dnim request-response, lahko stranka ponovno za\u017eene postopek obdelave datoteke, vendar bo status te obdelave pravilen. Ta to\u010dka deluje, v bistvu, \u017ee iz \u0161katle. Posledi\u010dno smo zdaj bolj tolerantni na napake.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"sharding\">Sharding<\/h1>\n<p><\/p>\n<p>Kot je \u017ee opisano zgoraj, v sistemih z event sourcingom ni stroge doslednosti. To pomeni, da lahko uporabljamo ve\u010d shranjevanj brez kakr\u0161ne koli sinhronizacije med njimi. Prihajajo\u010dih k na\u0161i nalogi, lahko:<\/p>\n<p><\/p>\n<ul>\n<li>Datoteke razdelimo po tipih. Na primer, slike\/video lahko dekodiramo in izberemo u\u010dinkovitej\u0161i format.<\/li>\n<li>Razdvajanje ra\u010dunov po dr\u017eavah. Zaradi mnogih zakonov je to lahko potrebno, toda ta arhitekturna shema ponuja to mo\u017enost samodejno.<\/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>\u010ce \u017eelite premakniti podatke iz enega skladi\u0161\u010da v drugo, pa brez standardnih sredstev ne bo \u0161lo. Na \u017ealost je v tem primeru potrebno ustaviti vrsto, izvesti migracijo in nato znova zagnati. Na splo\u0161no podatkov \"v \u017eivo\" ni mogo\u010de prenesti, vendar, \u010de je vrsta dogodkov popolnoma shranjena in imate kopije prej\u0161njih stanj skladi\u0161\u010da, lahko ponovno predvajamo dogodke na naslednji na\u010din:<\/p>\n<p><\/p>\n<ul>\n<li>V Event Source ima vsak dogodek svoj identifikator (ideally - nara\u0161\u010dajo\u010d). To pomeni, da lahko v skladi\u0161\u010de dodamo polje \u2014 id zadnjega obdelanega elementa.<\/li>\n<li>Dvojimo vrsto, da lahko vsi dogodki obdelujejo za ve\u010d neodvisnih skladi\u0161\u010d (prvo \u2014 to, v katerem so trenutno shranjeni podatki, in drugo \u2014 novo, ki pa je trenutno prazno). Druga vrsta se seveda zaenkrat ne obdeluje.<\/li>\n<li>Zacnemo drugo vrsto (to pomeni, da za\u010dnemo znova predvajati dogodke).<\/li>\n<li>Ko bo nova vrsta relativno prazna (t.j. povpre\u010dna razlika v \u010dasu med dodajanjem elementa in njegovim pridobivanjem bo sprejemljiva), lahko za\u010dnemo preklapljati bralce na novo skladi\u0161\u010de.<\/li>\n<\/ul>\n<p><\/p>\n<p>Kot je razvidno, v na\u0161em sistemu nikoli ni bilo in \u0161e vedno ni stroge doslednosti. Obstaja le eventualna doslednost, kar pomeni, da se dogodki obdelujejo v istem vrstnem redu (vendar morda z razli\u010dno zamudo). In z uporabo tega lahko relativno enostavno prenesemo podatke brez zaustavitve sistema na drug konec sveta.<\/p>\n<p><\/p>\n<p>Tako, kot nadaljujemo na\u0161 primer o spletnem skladi\u0161\u010du za datoteke, nam tak\u0161na arhitektura \u017ee prina\u0161a vrsto bonusov:<\/p>\n<p><\/p>\n<ul>\n<li>Objekte lahko premikamo bli\u017eje uporabnikom, in to dinami\u010dno. S tem lahko izbolj\u0161amo kakovost storitve. <\/li>\n<li>Del podatkov lahko hranimo znotraj podjetij. Na primer, uporabniki podjetij pogosto zahtevajo shranjevanje svojih podatkov v nadzorovanih podatkovnih centrih (da bi se izognili uhajanju podatkov). S pomo\u010djo sharding-a lahko to enostavno podpiramo. Naloga je \u0161e poenostavljena, \u010de ima naro\u010dnik zdru\u017eljivo obla\u010dno re\u0161itev (na primer, <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>Najpomembnej\u0161a stvar pa je, da tega morda ne bomo morali storiti. Za za\u010detek bi nam vsekakor zadostovalo eno skladi\u0161\u010de za vse ra\u010dune (da bi lahko hitreje za\u010deli delati). Klju\u010dna zna\u010dilnost tega sistema je, da je, \u010deprav raz\u0161irljiv, v za\u010detni fazi dovolj preprost. Preprosto povedano, ne smemo takoj pisati kode, ki deluje z milijonom lo\u010denih neodvisnih \u010dakalnih vrst itd. \u010ce bo potrebno, pa to lahko storimo v prihodnosti.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"static-content-hosting\">Gostovanje stati\u010dne vsebine<\/h1>\n<p><\/p>\n<p>Ta to\u010dka se morda zdi povsem o\u010ditna, a je kljub temu potrebna za povsem standardno obremenjeno aplikacijo. Njena bistvo je preprosto: vsa stati\u010dna vsebina se razdaja ne s tistega stre\u017enika, kjer je aplikacija, ampak s specializiranih stre\u017enikov, namenjenih prav temu. Posledi\u010dno se te operacije izvajajo hitreje (konvencionalni nginx dostavlja datoteke u\u010dinkoviteje in z manj stro\u0161ki kot Java stre\u017enik). Poleg tega arhitektura CDN (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Content_delivery_network\">Omre\u017eje za dostavo vsebine<\/a><\/noindex>) omogo\u010da postavitev na\u0161ih datotek bli\u017eje kon\u010dnim uporabnikom, kar pozitivno vpliva na priro\u010dnost dela s storitvijo.<\/p>\n<p><\/p>\n<p>Najpreprostej\u0161i in standardni primer stati\u010dne vsebine so zbirke skript in slik za spletno stran. Z njimi je vse preprosto \u2014 vnaprej so znane, nato se arhiv nalo\u017ei na stre\u017enike CDN, od koder se razdajo kon\u010dnim uporabnikom.<\/p>\n<p><\/p>\n<p>Vendar pa se v praksi za stati\u010dno vsebino lahko uporabi pristop, ki je nekako podoben lambda arhitekturi. Vrnimo se k na\u0161emu nalogu (spletno skladi\u0161\u010de datotek), pri katerem moramo datoteke razdeliti uporabnikom. Najpreprostej\u0161a re\u0161itev bi bila ustvariti storitev, ki za vsako uporabni\u0161ko zahtevo izvede vse potrebne preglede (avtorizacija itd.) in potem prenese datoteko neposredno iz na\u0161ega skladi\u0161\u010da. Glavna pomanjkljivost tega pristopa je, da se stati\u010dna vsebina (datoteka z dolo\u010deno revizijo je v bistvu stati\u010dna vsebina) deli s tistim samim stre\u017enikom, ki vsebuje poslovno logiko. Namesto tega lahko naredimo naslednjo shemo:<\/p>\n<p><\/p>\n<ul>\n<li>Stre\u017enik izda URL za prenos. Lahko je v obliki file_id + key, kjer je key mini-digitalni podpis, ki daje pravico dostopa do vira za naslednjih 24 ur.<\/li>\n<li>Prenos datoteke opravi preprost nginx z naslednjimi mo\u017enostmi:\n<ul>\n<li>Predpomnjenje vsebine. Ker ta storitev lahko deluje na lo\u010denem stre\u017eniku, smo si za prihodnost omogo\u010dili mo\u017enost shranjevanja vseh nedavno prenesenih datotek na disku.<\/li>\n<li>Preverjanje klju\u010da ob vzpostavitvi povezave.<\/li>\n<\/ul>\n<\/li>\n<li>Neobvezno: pretakanje vsebine. Na primer, \u010de komprimiramo vse datoteke v storitvi, lahko izvle\u010denje izvede prav ta modul. Posledi\u010dno so IO operacije opravljene na pravem mestu. Stisnitelj v Javi lahko zlahka porabi veliko odve\u010dnega pomnilnika, vendar je preklica storitve z poslovno logiko na pogojne Rust\/C++ lahko tudi neu\u010dinkovito. V na\u0161em primeru uporabljamo razli\u010dne procese (ali celo storitve), zato lahko razmeroma u\u010dinkovito lo\u010dimo poslovno logiko in 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>Tak\u0161na shema ni zelo podobna distribuciji stati\u010dne vsebine (ker celotnega sklopa statike ne nalagamo nekam), vendar v resnici ta pristop prav tako obravnava distribucijo nespremenljivih podatkov. Poleg tega se to shemo lahko posplo\u0161i tudi na druge primere, ko vsebina ni zgolj stati\u010dna, temve\u010d jo lahko predstavimo kot niz nespremenljivih in neizbrisanih blokov (\u010deprav se ti lahko dodajajo).<\/p>\n<p><\/p>\n<p>\u0160e en primer (za utrditev): \u010de ste delali z Jenkinsom\/TeamCityjem, potem veste, da sta obe re\u0161itvi napisani v Javi. Obe predstavljata Java proces, ki se ukvarja tako z orkestracijo gradnje kot z upravljanjem vsebine. V posebnosti imata naloge vrste \"prenesi datoteko\/mapo s stre\u017enika\". Kot primer: izdaja artefaktov, prenos izvorne kode (ko agent ne prenese kode neposredno iz repozitorija, temve\u010d to stori stre\u017enik), dostop do logov. Vse te naloge se razlikujejo po obremenitvi I\/O. Torej, stre\u017enik, ki odgovarja za kompleksno poslovno logiko, mora hkrati u\u010dinkovito obravnavati velike koli\u010dine podatkov. In kar je najzanimivej\u0161e, tovrstno operacijo je mogo\u010de delegirati istemu nginx-u po prav tako istem principu (le da je treba v zahtevo dodati klju\u010d podatkov).<\/p>\n<p><\/p>\n<p>Vendar \u010de se vrnemo k na\u0161emu sistemu, potem dobimo tak\u0161no shemo:<\/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>Kot je o\u010ditno, se je sistem radikalno zapletel. Zdaj to ni ve\u010d le mini-proces, ki lokalno shranjuje datoteke. Zdaj je potrebna \u017ee precej zahtevna podpora, nadzor razli\u010dic API itd. Zato je po tem, ko so vse sheme narisane, najbolje podrobno oceniti, ali se spla\u010da raz\u0161irljivost tak\u0161nih stro\u0161kov. \u010ce pa \u017eelite imeti mo\u017enost \u0161iriti sistem (tudi za delo z ve\u010djim \u0161tevilom uporabnikov), se boste morali odlo\u010diti za tak\u0161na re\u0161itev. Kljub temu je sistem arhitekturno pripravljen na obremenitev (prakti\u010dno vsak komponenta se lahko klonira za horizontalno skaliranje). Sistem je mogo\u010de posodabljati brez zaustavitve (le nekateri postopki bodo nekoliko upo\u010dasnjeni).<\/p>\n<p><\/p>\n<p>Kot sem \u017ee omenil na za\u010detku, so nekateri internetni servisi sedaj obremenjeni z ve\u010djo obremenitvijo. In nekateri od njih so enostavno prenehali delovati pravilno. V bistvu so sistemi odpovedali prav v trenutku, ko bi podjetje moralo zaslu\u017eiti. Namesto odlo\u017eene dostave, namesto ponudbe strankam 'na\u010drtujte dostavo za prihodnje mesece', je sistem enostavno rekel 'pojdite k konkurentom'. To je cena nizke zmogljivosti: izgube se zgodijo prav takrat, ko bi bila dobi\u010dek najvi\u0161ja.<\/p>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Zaklju\u010dek<\/h1>\n<p><\/p>\n<p>Vse te pristope smo poznali \u017ee prej. Enak VK \u017ee dolgo uporablja idejo Static Content Hosting za prikaz slik. Mno\u017eica spletnih iger uporablja shemo Sharding za razdelitev igralcev po regijah ali pa za razdelitev igralnih lokacij (\u010de je svet enoten). Pristop Event Sourcing se aktivno uporablja v elektronski po\u0161ti. Ve\u010dina aplikacij trgovcev, kjer neprekinjeno prihajajo podatki, je v resnici zgrajena na pristopu CQRS, da bi imele mo\u017enost filtrirati prejeto vsebino. Horizontalno skaliranje pa se \u017ee dolgo uporablja v mnogih storitvah.<\/p>\n<p><\/p>\n<p>Vendar pa, kar je najpomembneje, so postali vsi ti vzorci izjemno enostavni za uporabo v sodobnih aplikacijah (seveda, \u010de so smiselni). Oblaki ponujajo sharding in horizontalno skaliranje takoj, kar je precej la\u017eje, kot da sami naro\u010dite razli\u010dne namenski stre\u017enike v razli\u010dnih podatkovnih centrih. CQRS je postal precej la\u017eji predvsem zaradi razvoja knji\u017enic, kot je RX. Pred 10 leti bi redka spletna stran lahko podpirala tak\u0161no re\u0161itev. Event sourcing se prav tako nastavi neverjetno enostavno zahvaljujo\u010d \u017ee pripravljenim kontejnerjem s Apache Kafka. Pred 10 leti bi to bila novost, danes pa je to postalo rutina. Podobno velja za stati\u010dno gostovanje vsebine: zaradi bolj priro\u010dnih tehnologij (vklju\u010dno z ob\u0161irno dokumentacijo in veliko bazo odgovorov) je tak pristop postal \u0161e bolj enostaven.<\/p>\n<p><\/p>\n<p>Kot rezultat, je izvajanje vrste precej zapletenih arhitekturnih vzorcev zdaj postalo veliko la\u017eje, kar pomeni, da jih je bolje vnaprej preu\u010diti. \u010ce se je v desetletni aplikaciji od enega izmed zgoraj navedenih re\u0161itev odreklo zaradi visokih stro\u0161kov uvajanja in delovanja, pa je zdaj, v novi aplikaciji ali po refaktoringu, mogo\u010de narediti storitev, ki bo arhitekturno tako raz\u0161irljiva (z vidika zmogljivosti) kot pripravljena na nove zahteve strank (na primer za lokalizacijo osebnih podatkov).<\/p>\n<p><\/p>\n<p>In kar je najva\u017enej\u0161e: prosim, ne uporabljajte teh pristopov, \u010de imate preprosto aplikacijo. Da, so lepi in zanimivi, vendar je za spletno stran s vrhunskim obiskom 100 ljudi pogosto dovolj klasi\u010dni monolit (vsaj navzven, znotraj pa se lahko vse razdeli 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\/sl\/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=\"sl_SI\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\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\/sl\/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\udd47Udobni arhitekturni vzorci | ProHoster","description":"Pozdravljeni, Habr! V lu\u010di trenutnih dogodkov zaradi koronavirusa je vrsta internetnih storitev za\u010dela prejemati pove\u010dano obremenitev.","canonical_url":"https:\/\/prohoster.info\/sl\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sl_SI","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\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\/sl\/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\/sl\/wp-json\/wp\/v2\/posts\/80035","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/comments?post=80035"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/posts\/80035\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media\/80036"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/media?parent=80035"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/categories?post=80035"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sl\/wp-json\/wp\/v2\/tags?post=80035"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}