{"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\/sv\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny","title":{"rendered":"Praktiska arkitekturm\u00f6nster","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Hej, Habr!<\/p>\n<p><\/p>\n<p>I ljuset av den aktuella situationen p\u00e5 grund av coronaviruset har ett antal internettj\u00e4nster f\u00e5tt en \u00f6kad belastning. Till exempel, <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\">en av detaljhandelskedjorna i Storbritannien st\u00e4ngde bara ner sin webbplats f\u00f6r onlinebest\u00e4llningar,<\/a><\/noindex>, eftersom kapaciteten inte r\u00e4ckte till. Och det \u00e4r l\u00e5ngt ifr\u00e5n alltid m\u00f6jligt att snabba upp en server genom att helt enkelt l\u00e4gga till kraftfullare utrustning, \u00e4nd\u00e5 m\u00e5ste vi bearbeta kundernas f\u00f6rfr\u00e5gningar (eller s\u00e5 g\u00e5r de till konkurrenterna).<\/p>\n<p><\/p>\n<p>I den h\u00e4r artikeln kommer jag kort att ber\u00e4tta om popul\u00e4ra metoder som kan hj\u00e4lpa till att skapa en snabb och motst\u00e5ndskraftig tj\u00e4nst. Men bland de m\u00f6jliga utvecklingsscheman har jag valt ut bara de som \u00e4r <strong>l\u00e4tta att anv\u00e4nda.<\/strong>F\u00f6r varje punkt har du antingen redan f\u00e4rdiga bibliotek, eller s\u00e5 finns det m\u00f6jlighet att l\u00f6sa uppgiften med hj\u00e4lp av en molnplattform.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1 id=\"gorizontalnoe-masshtabirovanie\">Horisontell skalning<\/h1>\n<p><\/p>\n<p>Det enklaste och mest k\u00e4nda punkten. I allm\u00e4nhet finns det tv\u00e5 vanliga s\u00e4tt att f\u00f6rdela belastningen \u2014 horisontell och vertikal skalning. <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\">I det f\u00f6rsta fallet<\/a><\/noindex> l\u00e5ter du tj\u00e4nster arbeta parallellt, vilket f\u00f6rdelar belastningen mellan dem. <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\">I det andra<\/a><\/noindex> best\u00e4ller du kraftfullare servrar eller optimerar koden.<\/p>\n<p><\/p>\n<p>Som exempel tar jag ett abstrakt molnlagringssystem f\u00f6r filer, det vill s\u00e4ga en analog till OwnCloud, OneDrive och s\u00e5 vidare.<\/p>\n<p><\/p>\n<p>Den standardiserade bilden av en s\u00e5dan struktur nedan visar bara systemets komplexitet. F\u00f6r vi m\u00e5ste p\u00e5 n\u00e5got s\u00e4tt synkronisera tj\u00e4nsterna. Vad h\u00e4nder om en anv\u00e4ndare sparar en fil fr\u00e5n sin surfplatta och sedan vill titta p\u00e5 den fr\u00e5n sin telefon?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Praktiska arkitekturm\u00f6nster\" src=\"\/wp-content\/uploads\/2020\/05\/7512c6d8783f5e0a38cc0861b01e54c8.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nSkillnaden mellan metoderna: vid vertikal skalning \u00e4r vi beredda att \u00f6ka kapaciteten hos noderna, medan vi vid horisontell skalning l\u00e4gger till nya noder f\u00f6r att f\u00f6rdela belastningen.<\/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\">Command Query Responsibility Segregation<\/a><\/noindex> \u00e4r ett ganska viktigt m\u00f6nster eftersom det g\u00f6r det m\u00f6jligt f\u00f6r olika kunder att inte bara ansluta till olika tj\u00e4nster, utan ocks\u00e5 att f\u00e5 samma fl\u00f6den av h\u00e4ndelser. Dess f\u00f6rdelar \u00e4r inte s\u00e5 uppenbara f\u00f6r en enkel applikation, men den \u00e4r extremt viktig (och enkel) f\u00f6r en belastad tj\u00e4nst. K\u00e4rnan i detta \u00e4r att inkommande och utg\u00e5ende datastreamar inte b\u00f6r korsas. Det vill s\u00e4ga att du inte kan skicka en f\u00f6rfr\u00e5gan och f\u00f6rv\u00e4nta dig ett svar, ist\u00e4llet skickar du en f\u00f6rfr\u00e5gan till tj\u00e4nst A men f\u00e5r svaret i tj\u00e4nst B.<\/p>\n<p><\/p>\n<p>Den f\u00f6rsta f\u00f6rdelen med detta tillv\u00e4gag\u00e5ngss\u00e4tt \u00e4r m\u00f6jligheten att avbryta anslutningen (i bred mening av ordet) under processen av ett l\u00e5ngvarigt beg\u00e4ran. Som exempel kan vi ta en mer eller mindre standardiserad sekvens:<\/p>\n<p><\/p>\n<ol>\n<li>Klienten skickade en beg\u00e4ran till servern.<\/li>\n<li>Servern p\u00e5b\u00f6rjade en l\u00e5ngvarig bearbetning.<\/li>\n<li>Servern svarade klienten med resultatet.<\/li>\n<\/ol>\n<p><\/p>\n<p>T\u00e4nk dig att det i punkt 2 intr\u00e4ffade ett avbrott i kommunikationen (antingen \u00e5teransl\u00f6t n\u00e4tverket, eller s\u00e5 bytte anv\u00e4ndaren till en annan sida och avbr\u00f6t anslutningen). I detta fall kommer det att vara sv\u00e5rt f\u00f6r servern att skicka svar till anv\u00e4ndaren med information om vad som faktiskt har behandlats. Genom att anv\u00e4nda CQRS kommer sekvensen att vara n\u00e5got annorlunda:<\/p>\n<p><\/p>\n<ol>\n<li>Klienten har prenumererat p\u00e5 uppdateringar.<\/li>\n<li>Klienten skickade en beg\u00e4ran till servern.<\/li>\n<li>Servern svarade 'beg\u00e4ran mottagen'.<\/li>\n<li>Servern svarade med resultatet genom kanalen fr\u00e5n punkt '1'.<\/li>\n<\/ol>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Praktiska arkitekturm\u00f6nster\" src=\"\/wp-content\/uploads\/2020\/05\/8a00ea93eecc7cc0754122857c5f90d0.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Som man kan se \u00e4r schemat n\u00e5got mer komplext. Dessutom saknas det intuitiva tillv\u00e4gag\u00e5ngss\u00e4ttet request-response h\u00e4r. Men som man kan se kommer ett avbrott i kommunikationen under behandling av beg\u00e4ran inte att leda till ett fel. Dessutom, om anv\u00e4ndaren verkligen \u00e4r ansluten till tj\u00e4nsten med flera enheter (till exempel med en mobiltelefon och en surfplatta), kan man se till att svaret kommer till b\u00e5da enheterna.<\/p>\n<p><\/p>\n<p>Det intressanta \u00e4r att koden f\u00f6r behandling av inkommande meddelanden blir densamma (inte till 100%) f\u00f6r b\u00e5de h\u00e4ndelser som p\u00e5verkats av sj\u00e4lva klienten och f\u00f6r andra h\u00e4ndelser, inklusive fr\u00e5n andra kunder.<\/p>\n<p><\/p>\n<p>Men i praktiken f\u00e5r vi ytterligare f\u00f6rdelar eftersom den enkla str\u00f6mmen kan behandlas p\u00e5 funktionellt s\u00e4tt (med RX och liknande). Och det \u00e4r redan en stor f\u00f6rdel, eftersom applikationen i stort sett kan g\u00f6ras helt reaktiv, dessutom med hj\u00e4lp av ett funktionellt tillv\u00e4gag\u00e5ngss\u00e4tt. F\u00f6r mer omfattande program kan detta avsev\u00e4rt spara resurser vid utveckling och underh\u00e5ll.<\/p>\n<p><\/p>\n<p>Om man kombinerar detta tillv\u00e4gag\u00e5ngss\u00e4tt med horisontell skalning f\u00e5r vi bonusen av att kunna skicka beg\u00e4rningar till en server och f\u00e5 svar fr\u00e5n en annan. P\u00e5 s\u00e5 s\u00e4tt kan klienten sj\u00e4lv v\u00e4lja en tj\u00e4nst som passar dem, och systemet kan p\u00e5 insidan \u00e4nd\u00e5 korrekt bearbeta h\u00e4ndelser.<\/p>\n<p><\/p>\n<h1 id=\"event-sourcing\">Event Sourcing<\/h1>\n<p><\/p>\n<p>Som ni vet \u00e4r en av de fr\u00e4msta egenskaperna hos ett distribuerat system avsaknaden av gemensam tid och gemensam kritisk sektion. F\u00f6r en enskild process kan du g\u00f6ra en synkronisering (p\u00e5 samma mutexar), d\u00e4r du \u00e4r s\u00e4ker p\u00e5 att ingen annan k\u00f6r den koden. Men f\u00f6r ett distribuerat system \u00e4r detta riskabelt eftersom det skulle inneb\u00e4ra overhead och d\u00f6da hela sk\u00f6nheten i skalbarhet \u2013 alla komponenter skulle \u00e4nd\u00e5 v\u00e4nta p\u00e5 varandra.<\/p>\n<p><\/p>\n<p>H\u00e4r f\u00e5r vi en viktig insikt \u2013 en snabb distribuerad system kan inte synkroniseras, f\u00f6r d\u00e5 minskar vi prestandan. \u00c5 andra sidan beh\u00f6ver vi ofta viss koherens mellan komponenterna. F\u00f6r detta kan vi anv\u00e4nda en metod med <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Eventual_consistency\">eventuell konsistens<\/a><\/noindex>, d\u00e4r det garanteras att, i avsaknad av data\u00e4ndringar under en viss tidsperiod efter den senaste uppdateringen, kommer alla f\u00f6rfr\u00e5gningar att returnera det senaste uppdaterade v\u00e4rdet.<\/p>\n<p><\/p>\n<p>Det \u00e4r viktigt att f\u00f6rst\u00e5 att strikt <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Consistency_model#Strict_consistency\">koherens<\/a><\/noindex>ofta till\u00e4mpas p\u00e5 klassiska databaser, d\u00e4r varje nod har identisk information (detta uppn\u00e5s ofta n\u00e4r en transaktion anses vara genomf\u00f6rd f\u00f6rst efter ett svar fr\u00e5n den andra servern). H\u00e4r finns vissa undantag p\u00e5 grund av isoleringsniv\u00e5er, men den \u00f6vergripande essensen f\u00f6rblir densamma \u2013 du kan leva i en helt koherent v\u00e4rld.<\/p>\n<p><\/p>\n<p>Men l\u00e5t oss \u00e5terg\u00e5 till den ursprungliga uppgiften. Om en del av systemet kan byggas med <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Eventual_consistency\">eventuell konsistens<\/a><\/noindex>, s\u00e5 kan vi bygga f\u00f6ljande schema.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Praktiska arkitekturm\u00f6nster\" src=\"\/wp-content\/uploads\/2020\/05\/33c80be6bc33bd897ca9b9e5525f9ae8.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Viktiga egenskaper hos denna metod:<\/p>\n<p><\/p>\n<ul>\n<li>Varje inkommande f\u00f6rfr\u00e5gan placeras i en k\u00f6.<\/li>\n<li>Under behandlingen av f\u00f6rfr\u00e5gan kan tj\u00e4nsten ocks\u00e5 placera uppgifter i andra k\u00f6er.<\/li>\n<li>Varje inkommande h\u00e4ndelse har ett identifieringsnummer (som beh\u00f6vs f\u00f6r deduplication).<\/li>\n<li>\u041e\u0447\u0435\u0440\u0435\u0434\u044c \u0438\u0434\u0435\u043e\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e \u0441\u0445\u0435\u043c\u0435 &quot;append only&quot;. \u0418\u0437 \u043d\u0435\u0451 \u043d\u0435\u043b\u044c\u0437\u044f \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0445.<\/li>\n<li>K\u00f6n arbetar enligt FIFO (urs\u00e4kta tautologin). Om det beh\u00f6vs f\u00f6r parallell bearbetning b\u00f6r f\u00f6rem\u00e5len flyttas till olika k\u00f6er i en av stegen.<\/li>\n<\/ul>\n<p><\/p>\n<p>Jag p\u00e5minner om att vi betraktar fallet av en online filserver. I detta fall kommer systemet att se ungef\u00e4r ut s\u00e5 h\u00e4r:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Praktiska arkitekturm\u00f6nster\" src=\"\/wp-content\/uploads\/2020\/05\/b95efb29545dcde1db9432d12d00a1b1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Det \u00e4r viktigt att tj\u00e4nsterna i diagrammet inte n\u00f6dv\u00e4ndigtvis betyder enskilda servrar. \u00c4ven processen kan vara densamma. Det viktiga \u00e4r n\u00e5got annat: ideologiskt \u00e4r dessa saker \u00e5tskilda p\u00e5 ett s\u00e5dant s\u00e4tt att det enkelt g\u00e5r att till\u00e4mpa horisontell skalning.<\/p>\n<p><\/p>\n<p>Och f\u00f6r tv\u00e5 anv\u00e4ndare kommer schemat att se ut s\u00e5 h\u00e4r (tj\u00e4nster avsedda f\u00f6r olika anv\u00e4ndare markeras med olika f\u00e4rger):<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Praktiska arkitekturm\u00f6nster\" src=\"\/wp-content\/uploads\/2020\/05\/4c4aadc8b9dd505c3ad743e69fee4fae.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>F\u00f6rdelarna med en s\u00e5dan kombination:<\/p>\n<p><\/p>\n<ul>\n<li>Tj\u00e4nsterna f\u00f6r informationsbehandling \u00e4r \u00e5tskilda. K\u00f6erna \u00e4r ocks\u00e5 \u00e5tskilda. Om vi beh\u00f6ver \u00f6ka systemets genomstr\u00f6mning beh\u00f6ver vi bara starta fler tj\u00e4nster p\u00e5 fler servrar.<\/li>\n<li>N\u00e4r vi f\u00e5r information fr\u00e5n en anv\u00e4ndare beh\u00f6ver vi inte v\u00e4nta p\u00e5 att all data ska sparas helt. Tv\u00e4rtom, det r\u00e4cker att vi svarar \"ok\", och sedan gradvis b\u00f6rja arbeta. Samtidigt j\u00e4mnar k\u00f6n ut toppar, eftersom till\u00e4gg av ett nytt objekt g\u00e5r snabbt, och anv\u00e4ndaren beh\u00f6ver inte v\u00e4nta p\u00e5 en fullst\u00e4ndig genomg\u00e5ng av hela cykeln.<\/li>\n<li>Som exempel har jag lagt till en dedupliceringstj\u00e4nst som f\u00f6rs\u00f6ker sammanfoga identiska filer. Om den jobbar l\u00e4nge i 1 % av fallen kommer kunden praktiskt taget inte att m\u00e4rka det (se ovan), vilket \u00e4r en stor f\u00f6rdel, eftersom vi inte l\u00e4ngre kr\u00e4ver hundra procent hastighet och tillf\u00f6rlitlighet.<\/li>\n<\/ul>\n<p><\/p>\n<p>Men nackdelarna blir ocks\u00e5 tydliga:<\/p>\n<p><\/p>\n<ul>\n<li>V\u00e5rt system har f\u00f6rlorat strikt konsistens. Det betyder att om man till exempel prenumererar p\u00e5 olika tj\u00e4nster kan man teoretiskt f\u00e5 olika tillst\u00e5nd (eftersom en av tj\u00e4nsterna kan hinna ta emot meddelandet fr\u00e5n den interna k\u00f6n). Som en annan f\u00f6ljd har systemet nu ingen gemensam tid. Det g\u00e5r allts\u00e5 inte att sortera alla h\u00e4ndelser endast efter ankomsttid, eftersom klockorna mellan servrarna kan vara osynkroniserade (dessutom \u00e4r samma tid p\u00e5 tv\u00e5 servrar en utopi).<\/li>\n<li>Inga h\u00e4ndelser kan nu helt enkelt \u00e5terskapas (som skulle kunna g\u00f6ras med en databas). Ist\u00e4llet m\u00e5ste man l\u00e4gga till en ny h\u00e4ndelse \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/stackoverflow.com\/questions\/49451237\/compensating-events-on-cqrs-es-architecture\">compensation event<\/a><\/noindex>, som kommer att \u00e4ndra det senaste tillst\u00e5ndet till det som kr\u00e4vs. Som ett exempel fr\u00e5n ett liknande omr\u00e5de: utan att skriva om historien (vilket \u00e4r negativt i vissa fall) kan man i git inte \u00e5ngra en commit, men man kan g\u00f6ra en speciell <noindex><a rel=\"nofollow\" href=\"https:\/\/git-scm.com\/docs\/git-revert\">rollback commit<\/a><\/noindex>, som i grunden bara kommer att \u00e5terst\u00e4lla det gamla tillst\u00e5ndet. Men i historiken kommer b\u00e5de den felaktiga commit och rollback att sparas.<\/li>\n<li>Dataschemat kan f\u00f6r\u00e4ndras fr\u00e5n version till version, men gamla h\u00e4ndelser kan nu inte uppdateras till den nya standarden (eftersom h\u00e4ndelser i princip inte kan \u00e4ndras).<\/li>\n<\/ul>\n<p><\/p>\n<p>Som vi ser passar Event Sourcing utm\u00e4rkt med CQRS. Dessutom \u00e4r det redan sv\u00e5rt att implementera ett system med effektiva och anv\u00e4ndarv\u00e4nliga k\u00f6er, utan att separera datastreams, eftersom vi d\u00e5 m\u00e5ste l\u00e4gga till synkroniseringspunkter som kommer att neutralisera hela den positiva effekten av k\u00f6erna. N\u00e4r man till\u00e4mpar b\u00e5da tillv\u00e4gag\u00e5ngss\u00e4tten samtidigt m\u00e5ste koden f\u00f6r programmet justeras n\u00e5got. I v\u00e5rt fall, n\u00e4r en fil skickas till servern, f\u00e5r vi bara \"okej\" som svar, vilket bara betyder att \"fil\u00f6verf\u00f6ringsoperationen har sparats\". Formellt sett betyder det inte att datan redan \u00e4r tillg\u00e4nglig p\u00e5 andra enheter (till exempel kan dedupliceringstj\u00e4nsten omstrukturera indexet). Men efter en tid kommer klienten att f\u00e5 en avisering i stil med \"fil X har sparats\".<\/p>\n<p><\/p>\n<p>Som ett resultat:<\/p>\n<p><\/p>\n<ul>\n<li>Antalet statuser f\u00f6r fil\u00f6verf\u00f6ring \u00f6kar: ist\u00e4llet f\u00f6r den klassiska \"fil skickad\" f\u00e5r vi tv\u00e5: \"fil tillagd i k\u00f6n p\u00e5 servern\" och \"fil sparad i lagringen\". Det senare betyder att andra enheter redan kan b\u00f6rja ta emot filen (med f\u00f6rbeh\u00e5ll f\u00f6r att k\u00f6erna arbetar med olika hastigheter).<\/li>\n<li>Eftersom informationen om \u00f6verf\u00f6ringen nu kommer via olika kanaler, m\u00e5ste vi hitta l\u00f6sningar f\u00f6r att f\u00e5 status p\u00e5 filbehandlingen. Som en f\u00f6ljd av detta: i motsats till det klassiska request-response, kan klienten startas om under filbehandlingen, men statusen f\u00f6r just denna bearbetning kommer att vara korrekt. Detta punkt fungerar i praktiken \"out of the box\". Som en f\u00f6ljd av detta \u00e4r vi nu mer toleranta mot fel.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"sharding\">Sharding<\/h1>\n<p><\/p>\n<p>Som redan beskrivits ovan, inom system med event sourcing finns det ingen strikt konsistens. Det betyder att vi kan anv\u00e4nda flera lagringsutrymmen utan n\u00e5gon synkronisering mellan dem. N\u00e4r vi n\u00e4rmar oss v\u00e5r uppgift kan vi:<\/p>\n<p><\/p>\n<ul>\n<li>Dela upp filer efter typer. Till exempel kan bilder\/video avkodas och ett mer effektivt format v\u00e4ljas.<\/li>\n<li>Separera konton efter l\u00e4nder. P\u00e5 grund av m\u00e5nga lagar kan detta kr\u00e4vas, men denna arkitekturschema m\u00f6jligg\u00f6r automatiskt detta.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Praktiska arkitekturm\u00f6nster\" src=\"\/wp-content\/uploads\/2020\/05\/dd310df700bc39c014d0105a3425fece.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Om du vill \u00f6verf\u00f6ra data fr\u00e5n en lagring till en annan beh\u00f6vs redan standardmetoder. Tyv\u00e4rr \u00e4r det n\u00f6dv\u00e4ndigt att stoppa k\u00f6n, g\u00f6ra migrationen och sedan starta den igen. Generellt sett kan data inte \u00f6verf\u00f6ras 'on-the-fly', men om h\u00e4ndelsek\u00f6n lagras helt och du har kopior av tidigare tillst\u00e5nd av lagringen kan vi \u00e5terspela h\u00e4ndelser p\u00e5 f\u00f6ljande s\u00e4tt:<\/p>\n<p><\/p>\n<ul>\n<li>I Event Source har varje h\u00e4ndelse sitt eget identifierare (idealiskt \u2014 icke minskande). Det betyder att vi kan l\u00e4gga till ett f\u00e4lt i lagringen \u2014 id f\u00f6r den senaste behandlade posten.<\/li>\n<li>Vi duplicerar k\u00f6n s\u00e5 att alla h\u00e4ndelser kan behandlas f\u00f6r flera oberoende lagringar (den f\u00f6rsta \u00e4r den d\u00e4r data redan lagras, och den andra \u00e4r ny, men f\u00f6r tillf\u00e4llet tom). Den andra k\u00f6n behandlas f\u00f6rst\u00e5s inte f\u00f6r n\u00e4rvarande.<\/li>\n<li>Vi startar den andra k\u00f6n (det vill s\u00e4ga vi p\u00e5b\u00f6rjar \u00e5terspelningen av h\u00e4ndelser).<\/li>\n<li>N\u00e4r den nya k\u00f6n relativt sett \u00e4r tom (dvs. den genomsnittliga tidsdifferensen mellan till\u00e4gg av ett objekt och dess uttag \u00e4r acceptabel) kan vi b\u00f6rja v\u00e4xla l\u00e4sare till den nya lagringen.<\/li>\n<\/ul>\n<p><\/p>\n<p>Som vi kan se har vi i v\u00e5rt system varken haft eller har strikt \u00f6verensst\u00e4mmelse. Det finns bara eventual consistency, det vill s\u00e4ga en garanti f\u00f6r att h\u00e4ndelser behandlas i samma ordning (men eventuellt med olika f\u00f6rdr\u00f6jningar). Och genom att utnyttja detta kan vi relativt enkelt flytta data utan att stoppa systemet till andra sidan av jorden.<\/p>\n<p><\/p>\n<p>S\u00e5ledes, forts\u00e4tter v\u00e5rt exempel om en online-lagring f\u00f6r filer, ger denna arkitektur oss redan ett antal f\u00f6rdelar:<\/p>\n<p><\/p>\n<ul>\n<li>Vi kan flytta objekt n\u00e4rmare anv\u00e4ndarna, och detta g\u00f6rs dynamiskt. P\u00e5 s\u00e5 s\u00e4tt kan vi f\u00f6rb\u00e4ttra kvaliteten p\u00e5 tj\u00e4nsten. <\/li>\n<li>Vi kan lagra en del av data inom f\u00f6retagen. Till exempel kr\u00e4ver Enterprise-anv\u00e4ndare ofta att lagra sina data i kontrollerade datacenter (f\u00f6r att f\u00f6rhindra dataintr\u00e5ng). Genom sharding kan vi enkelt st\u00f6dja detta. Och uppgiften f\u00f6renklas ytterligare om kunden har en kompatibel molnl\u00f6sning (till exempel, <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>Och det viktigaste \u00e4r att vi kanske inte beh\u00f6ver g\u00f6ra det. F\u00f6r i b\u00f6rjan skulle ett enda lagringsutrymme f\u00f6r alla konton vara tillr\u00e4ckligt (s\u00e5 att vi snabbt kan b\u00f6rja arbeta). Och den centrala egenskapen hos detta system \u00e4r, \u00e4ven om det \u00e4r skalbart, att det i b\u00f6rjan \u00e4r ganska enkelt. Man beh\u00f6ver helt enkelt inte skriva kod som arbetar med en miljon separata oberoende k\u00f6er och s\u00e5 vidare direkt. Om det beh\u00f6vs kan det g\u00f6ras i framtiden.<\/li>\n<\/ul>\n<p><\/p>\n<h1 id=\"static-content-hosting\">Statisk Inneh\u00e5lls-hosting<\/h1>\n<p><\/p>\n<p>Denna punkt kan verka helt uppenbar, men den \u00e4r \u00e4nd\u00e5 n\u00f6dv\u00e4ndig f\u00f6r ett mer eller mindre standardbelastat program. Dess k\u00e4rna \u00e4r enkel: allt statiskt inneh\u00e5ll levereras inte fr\u00e5n samma server som applikationen, utan fr\u00e5n s\u00e4rskilda servrar som \u00e4r avsedda f\u00f6r detta. Som en f\u00f6ljd av detta utf\u00f6rs dessa operationer snabbare (exempelvis levererar nginx filer snabbare och mer kostnadseffektivt \u00e4n en Java-server). Dessutom m\u00f6jligg\u00f6r arkitekturen f\u00f6r CDN (<noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Content_delivery_network\">Inneh\u00e5llsleveransn\u00e4tverk<\/a><\/noindex>) att placera v\u00e5ra filer n\u00e4rmare slutanv\u00e4ndarna, vilket positivt p\u00e5verkar anv\u00e4ndarv\u00e4nligheten.<\/p>\n<p><\/p>\n<p>Det enklaste och mest standardiserade exemplet p\u00e5 statiskt inneh\u00e5ll \u00e4r en upps\u00e4ttning skript och bilder f\u00f6r en webbplats. Det \u00e4r enkelt \u2014 de \u00e4r k\u00e4nda p\u00e5 f\u00f6rhand, och arkivet laddas upp p\u00e5 CDN-servrarna, fr\u00e5n vilka det distribueras till slutanv\u00e4ndarna.<\/p>\n<p><\/p>\n<p>Men i verkligheten kan en n\u00e5got liknande metod som lambda-arkitekturen till\u00e4mpas f\u00f6r statiskt inneh\u00e5ll. L\u00e5t oss \u00e5terv\u00e4nda till v\u00e5rt uppdrag (ett online lagringsutrymme f\u00f6r filer), d\u00e4r vi beh\u00f6ver distribuera filer till anv\u00e4ndarna. Den enklaste l\u00f6sningen \u00e4r att skapa en tj\u00e4nst som f\u00f6r varje anv\u00e4ndarf\u00f6rfr\u00e5gan g\u00f6r alla n\u00f6dv\u00e4ndiga kontroller (auktorisering och s\u00e5 vidare) och sedan laddar ner filen direkt fr\u00e5n v\u00e5rt lagringsutrymme. Huvudnackdelen med denna metod \u00e4r att det statiska inneh\u00e5llet (och en fil med en specifik_revision fungerar i grunden som statiskt inneh\u00e5ll) levereras av samma server som inneh\u00e5ller aff\u00e4rslogiken. Ist\u00e4llet kan man g\u00f6ra f\u00f6ljande schema:<\/p>\n<p><\/p>\n<ul>\n<li>Servern ger en URL f\u00f6r nedladdning. Den kan se ut som file_id + key, d\u00e4r key \u00e4r en miniatyrdigital signatur som ger tillg\u00e5ng till resursen under de n\u00e4rmaste 24 timmarna.<\/li>\n<li>Nedladdningen av filen hanteras av en enkel nginx med f\u00f6ljande alternativ:\n<ul>\n<li>Caching av inneh\u00e5ll. Eftersom den h\u00e4r tj\u00e4nsten kan vara p\u00e5 en separat server har vi kvar en framtidsl\u00f6sning f\u00f6r att lagra alla de senaste nedladdade filerna p\u00e5 disken.<\/li>\n<li>Nyckelkontroll vid anslutningsskapande<\/li>\n<\/ul>\n<\/li>\n<li>Valfritt: str\u00f6mmande bearbetning av inneh\u00e5ll. Till exempel, om vi komprimerar alla filer i tj\u00e4nsten, kan vi g\u00f6ra dekomprimeringen direkt i denna modul. Som en f\u00f6ljd: IO-operationer genomf\u00f6rs d\u00e4r de h\u00f6r hemma. En Java-arkivare kan l\u00e4tt anv\u00e4nda mycket extra minne, men att skriva om tj\u00e4nsten med aff\u00e4rslogik p\u00e5 rust\/c++ kan visa sig vara ineffektivt. I v\u00e5rt fall anv\u00e4nds olika processer (eller till och med tj\u00e4nster), s\u00e5 vi kan effektivt separera aff\u00e4rslogik och IO-operationer.<\/li>\n<\/ul>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Praktiska arkitekturm\u00f6nster\" src=\"\/wp-content\/uploads\/2020\/05\/4dead07d5824938e09b986192ccc8f5e.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Denna typ av schema liknar inte mycket p\u00e5 distribution av statiskt inneh\u00e5ll (eftersom vi inte laddar upp hela paketet med statik n\u00e5gonstans), men i verkligheten hanterar denna metod just distribution av of\u00f6r\u00e4nderliga data. Dessutom kan detta schema generaliseras till andra fall d\u00e4r inneh\u00e5llet inte bara \u00e4r statiskt utan kan presenteras i form av en upps\u00e4ttning of\u00f6r\u00e4nderliga och oelimineringbara block (\u00e4ven om de kan l\u00e4ggas till).<\/p>\n<p><\/p>\n<p>\u041a\u0430\u043a \u0435\u0449\u0435 \u043f\u0440\u0438\u043c\u0435\u0440 (\u0434\u043b\u044f \u0437\u0430\u043a\u0440\u0435\u043f\u043b\u0435\u043d\u0438\u044f): \u0435\u0441\u043b\u0438 \u0432\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441 Jenkins\/TeamCity, \u0442\u043e \u0437\u043d\u0430\u0435\u0442\u0435, \u0447\u0442\u043e \u043e\u0431\u0430 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0430 Java. \u041e\u0431\u0430 \u043e\u043d\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0441\u043e\u0431\u043e\u0439 Java-\u043f\u0440\u043e\u0446\u0435\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043e\u0440\u043a\u0435\u0441\u0442\u0440\u0430\u0446\u0438\u0435\u0439 \u0431\u0438\u043b\u0434\u043e\u0432, \u0442\u0430\u043a \u0438 \u043c\u0435\u043d\u0435\u0434\u0436\u043c\u0435\u043d\u0442\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u0430. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0443 \u043d\u0438\u0445 \u043e\u0431\u043e\u0438\u0445 \u0435\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0438 \u0432\u0438\u0434\u0430 &quot;\u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0444\u0430\u0439\u043b\/\u043f\u0430\u043f\u043a\u0443 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430&quot;. \u041a\u0430\u043a \u043f\u0440\u0438\u043c\u0435\u0440: \u0432\u044b\u0434\u0430\u0447\u0430 \u0430\u0440\u0442\u0435\u0444\u0430\u043a\u0442\u043e\u0432, \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 (\u043a\u043e\u0433\u0434\u0430 \u0430\u0433\u0435\u043d\u0442 \u043d\u0435 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u0434 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u0437 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f, \u0430 \u0437\u0430 \u043d\u0435\u0433\u043e \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0441\u0435\u0440\u0432\u0435\u0440), \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043b\u043e\u0433\u0430\u043c. \u0412\u0441\u0435 \u044d\u0442\u0438 \u0437\u0430\u0434\u0430\u0447\u0438 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u043d\u0430 IO. \u0422\u043e \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u0441\u0435\u0440\u0432\u0435\u0440, \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0438\u0439 \u0437\u0430 \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u0431\u0438\u0437\u043d\u0435\u0441-\u043b\u043e\u0433\u0438\u043a\u0443, \u0437\u0430\u043e\u0434\u043d\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u043c\u0435\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u043f\u0440\u043e\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0431\u044f \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u043f\u043e\u0442\u043e\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u0418 \u0447\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435, \u043f\u043e\u0434\u043e\u0431\u043d\u0443\u044e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0435\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043c\u0443 \u0436\u0435 nginx&#8217;\u0443 \u043f\u043e \u0440\u043e\u0432\u043d\u043e \u0442\u043e\u0439 \u0436\u0435 \u0441\u0445\u0435\u043c\u0435 (\u0440\u0430\u0437\u0432\u0435 \u0447\u0442\u043e \u0432 \u0437\u0430\u043f\u0440\u043e\u0441 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u043b\u044e\u0447 \u0434\u0430\u043d\u043d\u044b\u0445).<\/p>\n<p><\/p>\n<p>Men om vi \u00e5terg\u00e5r till v\u00e5rt system, s\u00e5 ser vi ett s\u00e5dant schema:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Praktiska arkitekturm\u00f6nster\" src=\"\/wp-content\/uploads\/2020\/05\/97cfbf5daaa6678a9eecc3169692f0fc.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Som det framg\u00e5r har systemet blivit radikalt mer komplicerat. Det \u00e4r inte l\u00e4ngre bara en mini-process som lagrar filer lokalt. Nu kr\u00e4vs inte bara enklare support, utan ocks\u00e5 versionskontroll av API:er osv. D\u00e4rf\u00f6r, efter att alla diagram har ritats, \u00e4r det b\u00e4st att noggrant \u00f6verv\u00e4ga om kostnaderna f\u00f6r skalbarheten \u00e4r v\u00e4rda det. Men om du vill ha m\u00f6jlighet att skala systemet (inklusive f\u00f6r att arbeta med \u00e4nnu fler anv\u00e4ndare), m\u00e5ste du acceptera s\u00e5dana l\u00f6sningar. Som ett resultat \u00e4r systemets arkitektur redo f\u00f6r \u00f6kad belastning (n\u00e4stan varje komponent kan klonas f\u00f6r horisontell skalning). Systemet kan uppdateras utan att st\u00e4ngas ner (enbart vissa operationer kan bromsas n\u00e5got).<\/p>\n<p><\/p>\n<p>Som jag n\u00e4mnde i b\u00f6rjan, har flera internet-tj\u00e4nster nu f\u00e5tt \u00f6kad belastning. Och vissa av dem har helt enkelt slutat fungera korrekt. I sj\u00e4lva verket misslyckades systemen precis n\u00e4r f\u00f6retagen skulle b\u00f6rja tj\u00e4na pengar. Det vill s\u00e4ga, ist\u00e4llet f\u00f6r att skjuta fram leveranser, ist\u00e4llet f\u00f6r att erbjuda kunderna \"planera leveranser \u00f6ver de kommande m\u00e5naderna\", sa systemet helt enkelt \"g\u00e5 till konkurrenterna\". Och det \u00e4r kostnaden f\u00f6r l\u00e5g prestanda: f\u00f6rluster kommer att intr\u00e4ffa precis n\u00e4r vinsten skulle vara som h\u00f6gst.<\/p>\n<p><\/p>\n<h1 id=\"zaklyuchenie\">Slutsats<\/h1>\n<p><\/p>\n<p>Alla dessa tillv\u00e4gag\u00e5ngss\u00e4tt har varit k\u00e4nda tidigare. VK har l\u00e4nge anv\u00e4nt id\u00e9n om Static Content Hosting f\u00f6r att leverera bilder. M\u00e5nga online-spel anv\u00e4nder en Sharding-plan f\u00f6r att dela upp spelare efter regioner eller f\u00f6r att dela upp spelmilj\u00f6er (om v\u00e4rlden \u00e4r en enhet). Event Sourcing-ansatsen anv\u00e4nds aktivt inom e-post. De flesta handelsapplikationer, d\u00e4r data kontinuerligt kommer in, \u00e4r faktiskt byggda p\u00e5 CQRS-ansatsen f\u00f6r att kunna filtrera den mottagna datan. Och horisontell skalning har anv\u00e4nts l\u00e4nge i m\u00e5nga tj\u00e4nster.<\/p>\n<p><\/p>\n<p>Men det viktigaste \u00e4r att alla dessa m\u00f6nster har blivit mycket l\u00e4tta att till\u00e4mpa i moderna applikationer (om de \u00e4r relevanta, f\u00f6rst\u00e5s). Molntj\u00e4nster erbjuder sharding och horisontell skalning som standard, vilket \u00e4r mycket enklare \u00e4n att best\u00e4lla olika dedikerade servrar i olika datacenter sj\u00e4lv. CQRS har blivit mycket enklare, delvis tack vare utvecklingen av bibliotek som RX. F\u00f6r tio \u00e5r sedan skulle en s\u00e4llsynt webbplats kunna st\u00f6dja s\u00e5dana saker. Event sourcing st\u00e4ller in sig ocks\u00e5 otroligt l\u00e4tt tack vare redan f\u00e4rdiga containrar med Apache Kafka. F\u00f6r tio \u00e5r sedan hade detta varit en innovation, nu \u00e4r det en sj\u00e4lvklarhet. P\u00e5 samma s\u00e4tt med statisk inneh\u00e5llshosting: p\u00e5 grund av mer anv\u00e4ndarv\u00e4nlig teknik (d\u00e4ribland f\u00f6r att det finns detaljerad dokumentation och en stor databas med svar), har denna metod blivit \u00e4nnu enklare.<\/p>\n<p><\/p>\n<p>Som en f\u00f6ljd har implementeringen av ett antal ganska komplexa arkitektoniska m\u00f6nster nu blivit mycket enklare, vilket g\u00f6r att man b\u00f6r se n\u00e4rmare p\u00e5 dem i f\u00f6rv\u00e4g. Om ett tio\u00e5rigt program \u00f6vergav en av de ovanst\u00e5ende l\u00f6sningarna p\u00e5 grund av h\u00f6ga kostnader f\u00f6r implementering och drift, kan man nu, i ett nytt program, eller efter refaktorisering, skapa en tj\u00e4nst som arkitektoniskt redan kommer att vara b\u00e5de skalbar (med avseende p\u00e5 prestanda) och redo f\u00f6r nya krav fr\u00e5n kunderna (till exempel f\u00f6r lokalisering av personuppgifter).<\/p>\n<p><\/p>\n<p>Och det viktigaste: anv\u00e4nd inte dessa metoder om ni har en enkel applikation. Ja, de \u00e4r vackra och intressanta, men f\u00f6r en webbplats med en toppbes\u00f6kare p\u00e5 100 personer kan man ofta klara sig med en klassisk monolit (\u00e5tminstone utv\u00e4ndigt, internt kan allt brytas ner i moduler etc.).<\/p>\n<p>K\u00e4lla: <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\/sv\/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=\"sv_SE\" \/>\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\/sv\/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\udd47Bekv\u00e4ma arkitektoniska m\u00f6nster | ProHoster","description":"Hej, Habr! I ljuset av de aktuella h\u00e4ndelserna p\u00e5 grund av coronaviruset har en rad internettj\u00e4nster b\u00f6rjat f\u00e5 \u00f6kad belastning.","canonical_url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/udobnye-arhitekturnye-patterny","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"sv_SE","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\/sv\/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\/sv\/wp-json\/wp\/v2\/posts\/80035","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/comments?post=80035"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/80035\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media\/80036"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=80035"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=80035"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=80035"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}