{"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\/sv\/blog\/administrirovanie\/kak-kafka-stala-bylyu","title":{"rendered":"Hur Kafka blev verklighet","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Hur Kafka blev verklighet\" src=\"\/wp-content\/uploads\/2019\/12\/e61bf54b10e4e44a5c680185b0c16655.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hej, Habr!<\/p>\n<p><\/p>\n<p>Jag arbetar i Tinkoff-teamet som utvecklar v\u00e5rt eget notifieringscenter. St\u00f6rre delen av tiden utvecklar jag i Java med hj\u00e4lp av Spring Boot och l\u00f6ser olika tekniska problem som uppst\u00e5r i projektet.<\/p>\n<p><\/p>\n<p>De flesta av v\u00e5ra mikrotj\u00e4nster kommunicerar asynkront med varandra via en meddelandebroker. Tidigare anv\u00e4nde vi IBM MQ som broker, men den klarade inte belastningen l\u00e4ngre, trots att den hade h\u00f6ga leveransgarantier.<\/p>\n<p><\/p>\n<p>Som ett alternativ fick vi Apache Kafka, som har h\u00f6g skalbarhet, men tyv\u00e4rr kr\u00e4ver en n\u00e4stan skr\u00e4ddarsydd konfiguration f\u00f6r olika scenarier. Dessutom till\u00e4t mekanismen f\u00f6r \u00e5tminstone en leverans, som fungerar i Kafka som standard, inte att uppr\u00e4tth\u00e5lla den n\u00f6dv\u00e4ndiga niv\u00e5n av konsistens direkt. Jag kommer nu att dela v\u00e5r erfarenhet av att konfigurera Kafka, s\u00e4rskilt hur man st\u00e4ller in och lever med exakt en leverans.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"garantirovannaya-dostavka-i-ne-tolko\">Garanti f\u00f6r leverans och mer<\/h2>\n<p><\/p>\n<p>Parametrarna som vi kommer att diskutera nedan kan hj\u00e4lpa till att f\u00f6rebygga vissa problem med standardanslutningsinst\u00e4llningar. Men f\u00f6rst vill jag fokusera p\u00e5 en parameter som underl\u00e4ttar eventuell fels\u00f6kning.<\/p>\n<p><\/p>\n<p>Detta kommer att hj\u00e4lpa med <strong>client.id<\/strong> f\u00f6r Producer och Consumer. Vid f\u00f6rsta anblick kan man anv\u00e4nda applikationens namn som v\u00e4rde, och i de flesta fall fungerar det. Dock kan situationen d\u00e4r flera Consumers anv\u00e4nds i applikationen och man ger dem samma client.id leda till f\u00f6ljande varning:<\/p>\n<p><\/p>\n<pre><code class=\"java\">org.apache.kafka.common.utils.AppInfoParser \u2014 Fel vid registrering av AppInfo mbean javax.management.InstanceAlreadyExistsException: kafka.consumer:type=app-info,id=kafka.test-0<\/code><\/pre>\n<p><\/p>\n<p>Om du vill anv\u00e4nda JMX i en applikation med Kafka kan detta bli ett problem. I detta fall \u00e4r det b\u00e4st att anv\u00e4nda en kombination av applikationens namn och till exempel \u00e4mnets namn som v\u00e4rde f\u00f6r client.id. Resultatet av v\u00e5r konfiguration kan ses i utmatningen av kommandot <strong>kafka-consumer-groups<\/strong> fr\u00e5n verktygen fr\u00e5n Confluent:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Hur Kafka blev verklighet\" src=\"\/wp-content\/uploads\/2019\/12\/f807a93f36f262522a613161a549eb91.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nu ska vi g\u00e5 igenom scenariot f\u00f6r garanterad leverans av meddelanden. Kafka Producer har en parameter <strong>acks<\/strong>, som till\u00e5ter konfigurationen av efter hur m\u00e5nga acknowledgments som klusterledaren b\u00f6r betrakta meddelandet som framg\u00e5ngsrikt skrivet. Denna parameter kan ta f\u00f6ljande v\u00e4rden:<\/p>\n<p><\/p>\n<ul>\n<li>0 \u2014 acknowledgments kommer inte att r\u00e4knas.<\/li>\n<li>1 \u2014 standard parameter, acknowledgement is only required from 1 replica.<\/li>\n<li>\u22121 \u2014 acknowledgement is required from all synchronized replicas (cluster configuration) <strong>min.insync.replicas<\/strong>).<\/li>\n<\/ul>\n<p><\/p>\n<p>From the listed values, it is clear that acks equal to \u22121 provide the strongest guarantees that the message will not be lost. <\/p>\n<p><\/p>\n<p>As we all know, distributed systems are unreliable. To protect against temporary failures, Kafka Producer provides the parameter <strong>retries<\/strong>, which allows you to specify the number of retry attempts during <strong>delivery.timeout.ms<\/strong>. Since the retries parameter defaults to Integer.MAX_VALUE (2147483647), the number of message retries can be controlled by only changing delivery.timeout.ms.<\/p>\n<p><\/p>\n<h2 id=\"dvizhemsya-k-exactly-once-delivery\">Moving towards exactly once delivery<\/h2>\n<p><\/p>\n<p>The listed settings allow our Producer to deliver messages with a high guarantee. Now let\u2019s talk about how to ensure that only one copy of the message is written to the Kafka topic? In the simplest case, for this the Producer needs to set the parameter <strong>enable.idempotence<\/strong> to true. Idempotence guarantees that only one message is written to a specific partition of one topic. A prerequisite for enabling idempotence is the values <strong>acks = all, retry &gt; 0, max.in.flight.requests.per.connection \u2264 5<\/strong>. If these parameters are not set by the developer, the above values will be automatically assigned.<\/p>\n<p><\/p>\n<p>When idempotence is configured, it is necessary to ensure that the same messages go to the same partitions every time. This can be done by configuring the key and the partitioner.class parameter on the Producer. Let\u2019s start with the key. It must be the same for each delivery. This is easily achieved by using some business identifier from the original message. The partitioner.class parameter defaults to <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>. With this default partitioning strategy, we do the following:<\/p>\n<p><\/p>\n<ul>\n<li>If the partition is explicitly specified when sending the message, use it.<\/li>\n<li>If no partition is specified but a key is provided \u2014 choose the partition based on the hash of the key.<\/li>\n<li>If neither partition nor key is specified \u2014 select partitions in a round-robin manner.<\/li>\n<\/ul>\n<p><\/p>\n<p>In addition, using the key and idempotent sending with the parameter <strong>max.in.flight.requests.per.connection = 1<\/strong> ger en ordnad behandling av meddelanden i Consumer. Det \u00e4r viktigt att komma ih\u00e5g att om din kluster har inst\u00e4llningar f\u00f6r \u00e5tkomstkontroll, s\u00e5 kommer du att beh\u00f6va r\u00e4ttigheter f\u00f6r idempotent skrivning till \u00e4mnet.<\/p>\n<p><\/p>\n<p>Om du pl\u00f6tsligt saknar funktioner f\u00f6r idempotent s\u00e4ndning baserat p\u00e5 nyckel eller logik p\u00e5 Producer-sidan kr\u00e4ver bevarande av datakonsistens mellan olika partitioner, s\u00e5 kan transaktioner hj\u00e4lpa. Dessutom kan du med hj\u00e4lp av kedjetransaktioner villkorsbundet synkronisera skrivningen i Kafka, till exempel med skrivningen i en databas. F\u00f6r att aktivera transaktionell s\u00e4ndning p\u00e5 Producer m\u00e5ste den ha idempotens och dessutom ange <strong>transactional.id<\/strong>. Om din Kafka-kluster har inst\u00e4llningar f\u00f6r \u00e5tkomstkontroll, s\u00e5 kr\u00e4vs det ocks\u00e5 r\u00e4ttigheter f\u00f6r transaktionell skrivning, precis som f\u00f6r idempotent skrivning, som kan tillhandah\u00e5llas med en mask med hj\u00e4lp av v\u00e4rdet som lagras i transactional.id.<\/p>\n<p><\/p>\n<p>Formellt kan vilken str\u00e4ng som helst anv\u00e4ndas som transaktionsidentifierare, till exempel programmets namn. Men om du k\u00f6r flera instanser av samma program med samma transactional.id, d\u00e5 kommer den f\u00f6rsta instansen som startas att stoppas med ett fel, eftersom Kafka kommer att betrakta den som en zombiprocess. <\/p>\n<p><\/p>\n<pre><code class=\"java\">org.apache.kafka.common.errors.ProducerFencedException: Producenten f\u00f6rs\u00f6kte g\u00f6ra en operation med en gammal epok. Antingen finns det en nyare producent med samma transactionalId, eller s\u00e5 har producentens transaktion l\u00f6pt ut av broker.<\/code><\/pre>\n<p><\/p>\n<p>F\u00f6r att l\u00f6sa det h\u00e4r problemet l\u00e4gger vi till ett suffix till applikationsnamnet som \u00e4r v\u00e4rdnamnet, vilket vi f\u00e5r fr\u00e5n milj\u00f6variablerna. <\/p>\n<p><\/p>\n<p>Producenten \u00e4r konfigurerad, men transaktioner i Kafka hanterar endast meddelandets synlighet. Oavsett transaktionens status, g\u00e5r meddelandet direkt till \u00e4mnet men f\u00e5r ytterligare systemattribut.<\/p>\n<p><\/p>\n<p>F\u00f6r att s\u00e5dana meddelanden inte ska l\u00e4sas av Consumer innan tiden, m\u00e5ste den st\u00e4lla in parametern <strong>isolation.level<\/strong> till v\u00e4rdet read_committed. En s\u00e5dan Consumer kan l\u00e4sa icke-transaktionella meddelanden som tidigare, medan transaktionella endast kan l\u00e4sas efter commit.<br \/>\nOm du har st\u00e4llt in alla tidigare n\u00e4mnda inst\u00e4llningar, s\u00e5 har du konfigurerat exakt en g\u00e5ng-leverans. Grattis!<\/p>\n<p><\/p>\n<p>Men det finns en annan nuance. Transactional.id, som vi konfigurerade ovan, \u00e4r faktiskt en prefix f\u00f6r transaktionen. Till transaktionshanteraren l\u00e4ggs ett sekvensnummer till. Den identifierare som erh\u00e5lls utf\u00e4rdas f\u00f6r <strong>transactional.id.expiration.ms<\/strong>, som konfigureras p\u00e5 en Kafka-kluster och har ett standardv\u00e4rde p\u00e5 \"7 dagar\". Om applikationen under denna tid inte har mottagit n\u00e5gra meddelanden kommer du vid n\u00e4sta transaktionella s\u00e4ndning att f\u00e5 <strong>InvalidPidMappingException<\/strong>. D\u00e4refter kommer transaktionskoordinatorn att tilldela ett nytt sekvensnummer f\u00f6r n\u00e4sta transaktion. Medan detta meddelande kan g\u00e5 f\u00f6rlorat om InvalidPidMappingException inte hanteras korrekt. <\/p>\n<p><\/p>\n<h2 id=\"vmesto-itogov\">Ist\u00e4llet f\u00f6r sammanfattningar<\/h2>\n<p><\/p>\n<p>Som man kan se \u00e4r det inte tillr\u00e4ckligt att bara skicka meddelanden till Kafka. Man m\u00e5ste v\u00e4lja en kombination av parametrar och vara beredd p\u00e5 att g\u00f6ra snabba f\u00f6r\u00e4ndringar. I den h\u00e4r artikeln har jag f\u00f6rs\u00f6kt visa i detalj hur man konfigurerar exakt eng\u00e5ngsleverans och beskrivit flera konfigurationsproblem med client.id och transactional.id som vi st\u00f6tt p\u00e5. Nedan, i korthet, \u00e4r inst\u00e4llningarna f\u00f6r Producer och Consumer.<\/p>\n<p><\/p>\n<p>Producer:<\/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 f\u00f6r ordnad s\u00e4ndning)<\/li>\n<li>transactional.id = ${application-name}-${hostname}<\/li>\n<\/ol>\n<p><\/p>\n<p>Consumer:<\/p>\n<p><\/p>\n<ol>\n<li>isolation.level = read_committed<\/li>\n<\/ol>\n<p><\/p>\n<p>F\u00f6r att minimera fel i framtida applikationer har vi gjort v\u00e5rt eget wrapper \u00f6ver spring-konfigurationen, d\u00e4r v\u00e4rden redan \u00e4r angivna f\u00f6r n\u00e5gra av de angivna parametrarna.<\/p>\n<p><\/p>\n<p>H\u00e4r \u00e4r ett par resurser f\u00f6r sj\u00e4lvstudier:<\/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 Exakt eng\u00e5ngsleverans och transaktionsmeddelanden<\/a><\/noindex> <\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/kafka.apache.org\/documentation\/#configuration\">Beskrivning av inst\u00e4llningar <\/a><\/noindex><\/li>\n<\/ul>\n<p>K\u00e4lla: <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.4 - 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\/sv\/blog\/administrirovanie\/kak-kafka-stala-bylyu\" \/>\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\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\/sv\/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\udd47Hur Kafka blev verklighet | ProHoster","description":"Hej, Habr! Jag arbetar i Tinkoffs team.","canonical_url":"https:\/\/prohoster.info\/sv\/blog\/administrirovanie\/kak-kafka-stala-bylyu","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\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\/sv\/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\/sv\/wp-json\/wp\/v2\/posts\/54431","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=54431"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/posts\/54431\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/media?parent=54431"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/categories?post=54431"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/sv\/wp-json\/wp\/v2\/tags?post=54431"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}