{"id":54431,"date":"2019-12-26T00:00:00","date_gmt":"2019-12-25T21:00:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/blog_prohoster\/kak-kafka-stala-bylyu"},"modified":"2020-02-18T14:02:26","modified_gmt":"2020-02-18T11:02:26","slug":"kak-kafka-stala-bylyu","status":"publish","type":"post","link":"https:\/\/prohoster.info\/no\/blog\/administrirovanie\/kak-kafka-stala-bylyu","title":{"rendered":"Hvordan Kafka ble virkelighet","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Hvordan Kafka ble virkelighet\" src=\"\/wp-content\/uploads\/2019\/12\/e61bf54b10e4e44a5c680185b0c16655.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hei, Habr!<\/p>\n<p><\/p>\n<p>Eg jobbar i Tinkoff-teamet som utviklar v\u00e5rt eige varslingssenter. For det meste utviklar eg i Java med Spring Boot og l\u00f8ser ulike tekniske problem som oppst\u00e5r i prosjektet.<\/p>\n<p><\/p>\n<p>De fleste av v\u00e5re mikrotjenester kommuniserer asynkront med kvarandre via ein meldingsbroker. Tidlegare brukte vi IBM MQ som broker, men den klarte ikkje \u00e5 takle lasta lenger, sj\u00f8lv om den hadde h\u00f8ge leveringsgarantiar.<\/p>\n<p><\/p>\n<p>Som erstatning fekk vi anbefalt Apache Kafka, som har h\u00f8g skaleringspotensial, men som dessverre krev n\u00e6rare ein individuell tiln\u00e6rming til konfigurasjon for ulike scenario. I tillegg tillot mekanismen for minst ein gong levering, som fungerer i Kafka som standard, ikkje \u00e5 oppretthalde det n\u00f8dvendige niv\u00e5et av konsistens ut av boksen. Seinare vil eg dele v\u00e5r erfaring med konfigurering av Kafka, spesielt fortelje korleis ein kan sette opp og leve med n\u00f8yaktig ein gong levering.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"garantirovannaya-dostavka-i-ne-tolko\">Garantert levering og meir<\/h2>\n<p><\/p>\n<p>Parameters som vil bli omtala vidare, vil hjelpe til med \u00e5 unng\u00e5 ei rekkje problem med standard tilkoplingsinnstillingane. Men f\u00f8rst er det eit punkt eg gjerne vil fokusere p\u00e5, som vil lette mogleg debugging.<\/p>\n<p><\/p>\n<p>Dette vil hjelpast av <strong>client.id<\/strong> for Producer og Consumer. Ved f\u00f8rste augekast kan ein bruke applikasjonsnamnet som verdi, og i dei fleste tilfeller vil det fungere. Men situasjonen der applikasjonen har fleire Consumerar og de f\u00e5r same client.id, f\u00f8rer til f\u00f8lgjande advarsel:<\/p>\n<p><\/p>\n<pre><code class=\"java\">org.apache.kafka.common.utils.AppInfoParser \u2014 Error registering AppInfo mbean javax.management.InstanceAlreadyExistsException: kafka.consumer:type=app-info,id=kafka.test-0<\/code><\/pre>\n<p><\/p>\n<p>Dersom du vil bruke JMX i ein applikasjon med Kafka, kan dette bli eit problem. For dette tilfellet er det best \u00e5 bruke ein kombinasjon av applikasjonsnamn og til d\u00f8mes topiknamnet som verdi for client.id. Resultatet av v\u00e5r konfigurasjon kan sj\u00e5ast i utdataene fr\u00e5 kommandoen <strong>kafka-consumer-groups<\/strong> fr\u00e5 verkt\u00f8ya fr\u00e5 Confluent:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Hvordan Kafka ble virkelighet\" src=\"\/wp-content\/uploads\/2019\/12\/f807a93f36f262522a613161a549eb91.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>No skal vi sj\u00e5 p\u00e5 scenarioet for garantert levering av meldingar. Kafka Producer har parameteren <strong>acks<\/strong>, som lar deg konfigurere etter kor mange acknowledge leiarclusteret treng \u00e5 rekne med at meldinga er skriven vel. Denne parameteren kan ta f\u00f8lgjande verdiar:<\/p>\n<p><\/p>\n<ul>\n<li>0 \u2014 acknowledge vil ikkje bli rekna.<\/li>\n<li>1 \u2014 standardparameter, krev acknowledge berre fr\u00e5 1 replika.<\/li>\n<li>\u22121 \u2014 bekreftelser fra alle synkroniserte replikater er n\u00f8dvendig (klusterinnstilling) <strong>min.insync.replicas<\/strong>).<\/li>\n<\/ul>\n<p><\/p>\n<p>Av de oppf\u00f8rte verdiene er det klart at acks lik \u22121 gir de sterkeste garantiene for at meldingen ikke g\u00e5r tapt. <\/p>\n<p><\/p>\n<p>Som vi alle vet, er distribuerte systemer up\u00e5litelige. For \u00e5 beskytte seg mot midlertidige feil, gir Kafka Producer parameteren <strong>retries<\/strong>, som lar deg spesifisere antall fors\u00f8k p\u00e5 \u00e5 sende p\u00e5 nytt i l\u00f8pet av <strong>delivery.timeout.ms<\/strong>. Siden parameteren retries har standardverdi Integer.MAX_VALUE (2147483647), kan antall gjenutsendte meldinger justeres ved kun \u00e5 endre delivery.timeout.ms.<\/p>\n<p><\/p>\n<h2 id=\"dvizhemsya-k-exactly-once-delivery\">Vi beveger oss mot exactly once delivery<\/h2>\n<p><\/p>\n<p>De nevnte innstillingene lar v\u00e5r Producer levere meldinger med h\u00f8y sikkerhet. La oss n\u00e5 snakke om hvordan man kan garantere at bare \u00e9n kopi av meldingen skrives til Kafka-topikken? I det enkleste tilfellet m\u00e5 Produceren sette parameteren <strong>enable.idempotence<\/strong> til true. Idempotens garanterer at bare \u00e9n melding skrives til en bestemt partisjon av en topikk. Forutsetningen for \u00e5 aktivere idempotens er verdiene <strong>acks = all, retry &gt; 0, max.in.flight.requests.per.connection \u2264 5<\/strong>. Hvis disse alternativene ikke er spesifisert av utvikleren, vil de automatisk bli satt til de nevnte verdiene.<\/p>\n<p><\/p>\n<p>N\u00e5r idempotens er konfigurert, m\u00e5 man sikre at identiske meldinger alltid havner i de samme partisjonene. Dette kan gj\u00f8res ved \u00e5 konfigurere n\u00f8kkelen og parameteren partitioner.class p\u00e5 Producer. La oss begynne med n\u00f8kkelen. Den m\u00e5 v\u00e6re lik for hver sending. Dette er lett \u00e5 oppn\u00e5 ved \u00e5 bruke en forretningsidentifikator fra den originale meldingen. Parameteren partitioner.class har standardverdi \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/apache\/kafka\/blob\/trunk\/clients\/src\/main\/java\/org\/apache\/kafka\/clients\/producer\/internals\/DefaultPartitioner.java\">DefaultPartitioner<\/a><\/noindex>. Med denne standard partisjoneringsstrategien fungerer vi slik:<\/p>\n<p><\/p>\n<ul>\n<li>Hvis partisjonen er spesifisert ved sending av meldingen, bruker vi den.<\/li>\n<li>Hvis partisjonen ikke er spesifisert, men n\u00f8kkelen er angitt \u2014 velger vi partisjonen basert p\u00e5 hash av n\u00f8kkelen.<\/li>\n<li>Hvis verken partisjonen eller n\u00f8kkelen er spesifisert \u2014 velger vi partisjonene p\u00e5 rundgang (round-robin).<\/li>\n<\/ul>\n<p><\/p>\n<p>I tillegg, bruk av n\u00f8kkel og idempotent sending med parameteren <strong>max.in.flight.requests.per.connection = 1<\/strong> gir deg en organisert behandling av meldinger p\u00e5 Consumer. Det er ogs\u00e5 viktig \u00e5 huske at hvis clusteret ditt har tilgangskontroll aktivert, vil du trenge rettigheter for idempotent skriving til topic.<\/p>\n<p><\/p>\n<p>Hvis du mangler muligheten til idempotent sending etter n\u00f8kkel, eller logikken p\u00e5 produsentsiden krever at du opprettholder konsistens i data mellom forskjellige partisjoner, kan transaksjoner hjelpe. I tillegg kan du med kjedetransaksjoner betinget synkronisere skriving til Kafka, for eksempel med skriving til DB. For \u00e5 aktivere transaksjonell sending p\u00e5 produsenten m\u00e5 den v\u00e6re idempotent, og du m\u00e5 ogs\u00e5 angi <strong>transactional.id<\/strong>. Hvis Kafka-clusteret ditt har tilgangskontroll aktivert, trenger du som med idempotent skriving, skrivetilgang som kan gis via en maske ved \u00e5 bruke verdien lagret i transactional.id.<\/p>\n<p><\/p>\n<p>Formelt kan du bruke hvilken som helst streng som transaksjonsidentifikator, for eksempel navnet p\u00e5 applikasjonen. Men hvis du kj\u00f8rer flere instanser av den samme applikasjonen med samme transactional.id, vil den f\u00f8rste kj\u00f8rende instansen bli stoppet med en feil, da Kafka vil anse den som en zombieprosess. <\/p>\n<p><\/p>\n<pre><code class=\"java\">org.apache.kafka.common.errors.ProducerFencedException: Produsenten fors\u00f8kte en operasjon med en gammel epoke. Enten er det en nyere produsent med samme transactionalId, eller produsentens transaksjon har utl\u00f8pt p\u00e5 broker.<\/code><\/pre>\n<p><\/p>\n<p>For \u00e5 l\u00f8se dette problemet, legger vi til et suffiks til applikasjonsnavnet i form av vertsnavn, som vi f\u00e5r fra milj\u00f8variablene. <\/p>\n<p><\/p>\n<p>Produsenten er konfigurert, men transaksjoner i Kafka styrer kun synligheten av meldingen. Uansett status p\u00e5 transaksjonen, blir meldingen umiddelbart plassert i topic, men har ekstra systemattributter.<\/p>\n<p><\/p>\n<p>For at slike meldinger ikke skal bli lest av Consumer for tidlig, m\u00e5 den stille inn parameteren <strong>isolation.level<\/strong> til verdien read_committed. En slik Consumer kan lese ikke-transaksjonelle meldinger som f\u00f8r, men transaksjonelle meldinger kun etter commit.<br \/>\nHvis du har satt opp alle de f\u00f8rnevnte innstillingene, s\u00e5 har du konfigurert exactly once delivery. Gratulerer!<\/p>\n<p><\/p>\n<p>Men det er en annen nyanse. Transactional.id, som vi konfigurerte tidligere, er faktisk et prefiks for transaksjonen. P\u00e5 transaksjonslederen legges det til et sekvensnummer. Den resulterende identifikatoren utstedes ved <strong>transactional.id.expiration.ms<\/strong>, som er konfigurert p\u00e5 Kafka-klyngen og har en standardverdi p\u00e5 \u00ab7 dager\u00bb. Hvis applikasjonen ikke har mottatt noen meldinger i l\u00f8pet av denne tiden, vil du under det neste transaksjonsfors\u00f8ket f\u00e5 <strong>InvalidPidMappingException<\/strong>. Etter dette vil transaksjonskoordinatoren gi et nytt sekvensnummer for neste transaksjon. Meldingen kan bli tapt hvis ikke InvalidPidMappingException blir riktig h\u00e5ndtert. <\/p>\n<p><\/p>\n<h2 id=\"vmesto-itogov\">I stedet for oppsummeringer<\/h2>\n<p><\/p>\n<p>Som man kan se, er det ikke nok bare \u00e5 sende meldinger til Kafka. Man m\u00e5 velge en kombinasjon av parametere og v\u00e6re klar til \u00e5 gj\u00f8re raske endringer. I denne artikkelen har jeg pr\u00f8vd \u00e5 vise i detalj oppsettet for exactly once delivery, og jeg har beskrevet noen konfigurasjonsproblemer med client.id og transactional.id som vi har m\u00f8tt. Nedenfor er innstillingene for Produsent og Konsument oppsummert kort.<\/p>\n<p><\/p>\n<p>Produsent:<\/p>\n<p><\/p>\n<ol>\n<li>acks = all<\/li>\n<li>retries &gt; 0<\/li>\n<li>enable.idempotence = true<\/li>\n<li>max.in.flight.requests.per.connection \u2264 5 (1 \u2014 for ordnet sending)<\/li>\n<li>transactional.id = ${application-name}-${hostname}<\/li>\n<\/ol>\n<p><\/p>\n<p>Konsument:<\/p>\n<p><\/p>\n<ol>\n<li>isolation.level = read_committed<\/li>\n<\/ol>\n<p><\/p>\n<p>For \u00e5 minimere feil i fremtidige applikasjoner har vi laget et lag rundt spring-konfigurasjonen, hvor verdiene for noen av de nevnte parameterne allerede er satt.<\/p>\n<p><\/p>\n<p>Her er et par ressurser for selvstudium:<\/p>\n<p><\/p>\n<ul>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/cwiki.apache.org\/confluence\/display\/KAFKA\/KIP-98+-+Exactly+Once+Delivery+and+Transactional+Messaging\">KIP-98 \u2014 Exactly Once Delivery and Transactional Messaging<\/a><\/noindex> <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/kafka.apache.org\/documentation\/#configuration\">Beskrivelse av innstillingene <\/a><\/noindex><\/li>\n<\/ul>\n<p>Kilde: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/tinkoff\/blog\/481784\/\">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! \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 Tinkoff, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0446\u0435\u043d\u0442\u0440\u0430 \u043d\u043e\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0439. \u041f\u043e \u0431\u043e\u043b\u044c\u0448\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u044f \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e \u043d\u0430 Java \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Spring boot \u0438 \u0440\u0435\u0448\u0430\u044e \u0440\u0430\u0437\u043d\u044b\u0435 \u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u044e\u0449\u0438\u0435 \u0432 \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u0411\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e \u043d\u0430\u0448\u0438\u0445 \u043c\u0438\u043a\u0440\u043e\u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0430\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044e\u0442 \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c \u0447\u0435\u0440\u0435\u0437 \u0431\u0440\u043e\u043a\u0435\u0440 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u0420\u0430\u043d\u0435\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0431\u0440\u043e\u043a\u0435\u0440\u0430 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 IBM MQ, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043b \u0441\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0441 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-54431","post","type-post","status-publish","format-standard","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.5 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 Tinkoff.\" \/>\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\/no\/blog\/administrirovanie\/kak-kafka-stala-bylyu\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.5\" \/>\n\t\t<meta property=\"og:locale\" content=\"nn_NO\" \/>\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\u041a\u0430\u043a Kafka \u0441\u0442\u0430\u043b\u0430 \u0431\u044b\u043b\u044c\u044e | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 Tinkoff.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/no\/blog\/administrirovanie\/kak-kafka-stala-bylyu\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-12-25T21:00:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-02-18T11:02:26+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\udd47Hvordan Kafka ble en realitet | ProHoster","description":"Hei, Habr! Jeg jobber i Tinkoff-teamet.","canonical_url":"https:\/\/prohoster.info\/no\/blog\/administrirovanie\/kak-kafka-stala-bylyu","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"nn_NO","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\u041a\u0430\u043a Kafka \u0441\u0442\u0430\u043b\u0430 \u0431\u044b\u043b\u044c\u044e | ProHoster","og:description":"\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440! \u042f \u0440\u0430\u0431\u043e\u0442\u0430\u044e \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 Tinkoff.","og:url":"https:\/\/prohoster.info\/no\/blog\/administrirovanie\/kak-kafka-stala-bylyu","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-12-25T21:00:00+00:00","article:modified_time":"2020-02-18T11:02:26+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"54431","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-24 11:22:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 20:06:37","updated":"2026-01-24 11:22:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/posts\/54431","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/comments?post=54431"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/posts\/54431\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/media?parent=54431"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/categories?post=54431"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/no\/wp-json\/wp\/v2\/tags?post=54431"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}