{"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\/pt\/blog\/administrirovanie\/kak-kafka-stala-bylyu","title":{"rendered":"Como o Kafka se tornou uma realidade","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Como o Kafka se tornou uma realidade\" src=\"\/wp-content\/uploads\/2019\/12\/e61bf54b10e4e44a5c680185b0c16655.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ol\u00e1, Habr!<\/p>\n<p><\/p>\n<p>Eu trabalho na equipe do Tinkoff, que desenvolve um centro de notifica\u00e7\u00f5es pr\u00f3prio. Principalmente, desenvolvo em Java usando Spring Boot e resolvo v\u00e1rios problemas t\u00e9cnicos que surgem no projeto.<\/p>\n<p><\/p>\n<p>A maioria dos nossos microsservi\u00e7os interagem de forma ass\u00edncrona atrav\u00e9s de um broker de mensagens. Anteriormente, utilizamos o IBM MQ como broker, que n\u00e3o conseguiu lidar com a carga, mas tinha altas garantias de entrega.<\/p>\n<p><\/p>\n<p>Como substituto, nos foi sugerido o Apache Kafka, que possui um alto potencial de escalabilidade, mas, infelizmente, requer uma abordagem praticamente individual de configura\u00e7\u00e3o para diferentes cen\u00e1rios. Al\u00e9m disso, o mecanismo de entrega at least once, que opera no Kafka por padr\u00e3o, n\u00e3o permitia manter o n\u00edvel necess\u00e1rio de consist\u00eancia fora da caixa. A seguir, compartilharei nossa experi\u00eancia na configura\u00e7\u00e3o do Kafka, especificamente como configurar e viver com a entrega exactly once.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h2 id=\"garantirovannaya-dostavka-i-ne-tolko\">Entrega garantida e muito mais<\/h2>\n<p><\/p>\n<p>Os par\u00e2metros que discutiremos a seguir ajudar\u00e3o a evitar uma s\u00e9rie de problemas com as configura\u00e7\u00f5es de conex\u00e3o padr\u00e3o. Mas primeiro, vamos nos concentrar em um par\u00e2metro que facilitar\u00e1 a poss\u00edvel depura\u00e7\u00e3o.<\/p>\n<p><\/p>\n<p>Isso ajudar\u00e1 <strong>client.id<\/strong> para o Producer e o Consumer. \u00c0 primeira vista, pode-se usar o nome do aplicativo como valor, e na maioria das vezes isso funcionar\u00e1. No entanto, a situa\u00e7\u00e3o em que v\u00e1rias Consumers s\u00e3o usadas no aplicativo e voc\u00ea atribui o mesmo client.id a elas gera o seguinte aviso:<\/p>\n<p><\/p>\n<pre><code class=\"java\">org.apache.kafka.common.utils.AppInfoParser \u2014 Erro ao registrar AppInfo mbean javax.management.InstanceAlreadyExistsException: kafka.consumer:type=app-info,id=kafka.test-0<\/code><\/pre>\n<p><\/p>\n<p>Se voc\u00ea deseja usar JMX em um aplicativo com Kafka, isso pode ser um problema. Para essa situa\u00e7\u00e3o, \u00e9 melhor usar como valor do client.id uma combina\u00e7\u00e3o do nome do aplicativo e, por exemplo, o nome do t\u00f3pico. O resultado da nossa configura\u00e7\u00e3o pode ser visto na sa\u00edda do comando <strong>kafka-consumer-groups<\/strong> das ferramentas da Confluent:<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Como o Kafka se tornou uma realidade\" src=\"\/wp-content\/uploads\/2019\/12\/f807a93f36f262522a613161a549eb91.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Agora, vamos analisar o cen\u00e1rio de entrega garantida de mensagens. O Kafka Producer possui um par\u00e2metro <strong>acks<\/strong>, que permite configurar quantas confirma\u00e7\u00f5es o l\u00edder do cluster deve receber antes de considerar a mensagem escrita com sucesso. Este par\u00e2metro pode assumir os seguintes valores:<\/p>\n<p><\/p>\n<ul>\n<li>0 \u2014 confirma\u00e7\u00f5es n\u00e3o ser\u00e3o contabilizadas.<\/li>\n<li>1 \u2014 par\u00e2metro padr\u00e3o, necess\u00e1rio acknowledgment apenas de 1 r\u00e9plica.<\/li>\n<li>\u22121 \u2014 s\u00e3o necess\u00e1rios acknowledgments de todas as r\u00e9plicas sincronizadas (configura\u00e7\u00e3o do cluster. <strong>min.insync.replicas<\/strong>).<\/li>\n<\/ul>\n<p><\/p>\n<p>Dos valores listados, um acks igual a \u22121 oferece as garantias mais fortes de que a mensagem n\u00e3o ser\u00e1 perdida. <\/p>\n<p><\/p>\n<p>Como todos sabemos, sistemas distribu\u00eddos s\u00e3o n\u00e3o confi\u00e1veis. Para se proteger contra falhas tempor\u00e1rias, o Kafka Producer fornece o par\u00e2metro <strong>retries<\/strong>, que permite definir o n\u00famero de tentativas de reenvio dentro de <strong>delivery.timeout.ms<\/strong>. Como o par\u00e2metro retries tem um valor padr\u00e3o de Integer.MAX_VALUE (2147483647), o n\u00famero de reenvios de uma mensagem pode ser regulado apenas alterando o delivery.timeout.ms.<\/p>\n<p><\/p>\n<h2 id=\"dvizhemsya-k-exactly-once-delivery\">Avan\u00e7ando para a entrega exatamente uma vez<\/h2>\n<p><\/p>\n<p>As configura\u00e7\u00f5es listadas permitem que nosso Producer entregue mensagens com alta garantia. Agora vamos falar sobre como garantir a grava\u00e7\u00e3o de apenas uma c\u00f3pia da mensagem no t\u00f3pico Kafka? No caso mais simples, para isso o Producer deve definir o par\u00e2metro <strong>enable.idempotence<\/strong> como true. A idempot\u00eancia garante a grava\u00e7\u00e3o de apenas uma mensagem em uma parti\u00e7\u00e3o espec\u00edfica de um t\u00f3pico. Uma condi\u00e7\u00e3o pr\u00e9via para habilitar a idempot\u00eancia s\u00e3o os valores <strong>acks = all, retry &gt; 0, max.in.flight.requests.per.connection \u2264 5<\/strong>. Se esses par\u00e2metros n\u00e3o forem definidos pelo desenvolvedor, ent\u00e3o os valores mencionados acima ser\u00e3o aplicados automaticamente.<\/p>\n<p><\/p>\n<p>Quando a idempot\u00eancia est\u00e1 configurada, \u00e9 necess\u00e1rio garantir que mensagens id\u00eanticas cheguem sempre \u00e0s mesmas parti\u00e7\u00f5es. Isso pode ser feito configurando a chave e o par\u00e2metro partitioner.class no Producer. Vamos come\u00e7ar pela chave. Para cada envio, ela deve ser a mesma. Isso \u00e9 facilmente alcan\u00e7ado utilizando algum identificador de neg\u00f3cio da mensagem original. O par\u00e2metro partitioner.class tem o valor padr\u00e3o de <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>. Com esta estrat\u00e9gia de parti\u00e7\u00e3o padr\u00e3o, agimos da seguinte forma:<\/p>\n<p><\/p>\n<ul>\n<li>Se a parti\u00e7\u00e3o for explicitamente especificada ao enviar a mensagem, a utilizamos.<\/li>\n<li>Se a parti\u00e7\u00e3o n\u00e3o for especificada, mas a chave for, escolhemos a parti\u00e7\u00e3o com base no hash da chave.<\/li>\n<li>Se nem a parti\u00e7\u00e3o nem a chave forem especificadas \u2014 escolhemos as parti\u00e7\u00f5es em ordem (round-robin).<\/li>\n<\/ul>\n<p><\/p>\n<p>Al\u00e9m disso, o uso de chave e envio idempotente com o par\u00e2metro <strong>max.in.flight.requests.per.connection = 1<\/strong> oferece um processamento ordenado de mensagens no Consumer. \u00c9 importante lembrar que, se o gerenciamento de acesso estiver configurado em seu cluster, ser\u00e3o necess\u00e1rias permiss\u00f5es para escrita idempotente no t\u00f3pico.<\/p>\n<p><\/p>\n<p>Se por acaso voc\u00ea sentir falta das capacidades de envio idempotente por chave ou se a l\u00f3gica do lado do Producer exigir a manuten\u00e7\u00e3o da consist\u00eancia de dados entre diferentes parti\u00e7\u00f5es, as transa\u00e7\u00f5es podem ser a solu\u00e7\u00e3o. Al\u00e9m disso, com transa\u00e7\u00f5es encadeadas, voc\u00ea pode condicionalmente sincronizar a grava\u00e7\u00e3o no Kafka, por exemplo, com uma grava\u00e7\u00e3o no banco de dados. Para habilitar o envio transacional no Producer, \u00e9 necess\u00e1rio que ele tenha idempot\u00eancia e voc\u00ea tamb\u00e9m deve definir <strong>transactional.id<\/strong>. Se o seu cluster Kafka tiver gerenciamento de acesso habilitado, ent\u00e3o para a grava\u00e7\u00e3o transacional, assim como para a idempotente, ser\u00e3o necess\u00e1rias permiss\u00f5es de grava\u00e7\u00e3o que podem ser concedidas por meio de uma m\u00e1scara com o valor armazenado em transactional.id.<\/p>\n<p><\/p>\n<p>Formalmente, qualquer string pode ser usada como identificador de transa\u00e7\u00e3o, por exemplo, o nome do aplicativo. Mas se voc\u00ea estiver executando v\u00e1rias inst\u00e2ncias de um mesmo aplicativo com o mesmo transactional.id, a primeira inst\u00e2ncia iniciada ser\u00e1 interrompida com um erro, pois o Kafka a considerar\u00e1 um processo zumbi. <\/p>\n<p><\/p>\n<pre><code class=\"java\">org.apache.kafka.common.errors.ProducerFencedException: O Producer tentou realizar uma opera\u00e7\u00e3o com uma epoch antiga. Ou existe um producer mais novo com o mesmo transactionalId, ou a transa\u00e7\u00e3o do producer expirou no broker.<\/code><\/pre>\n<p><\/p>\n<p>Para resolver esse problema, adicionamos um sufixo ao nome do aplicativo a partir do nome do host, obtido das vari\u00e1veis de ambiente. <\/p>\n<p><\/p>\n<p>O Producer est\u00e1 configurado, mas as transa\u00e7\u00f5es no Kafka controlam apenas o escopo da mensagem. Independentemente do status da transa\u00e7\u00e3o, a mensagem \u00e9 imediatamente enviada ao t\u00f3pico, mas possui atributos de sistema adicionais.<\/p>\n<p><\/p>\n<p>Para que essas mensagens n\u00e3o sejam lidas pelo Consumer antes do tempo, \u00e9 necess\u00e1rio configurar o par\u00e2metro <strong>isolation.level<\/strong> para o valor read_committed. Esse Consumer poder\u00e1 ler mensagens n\u00e3o transacionais como antes, e as transacionais somente ap\u00f3s o commit.<br \/>\nSe voc\u00ea configurou todas as configura\u00e7\u00f5es mencionadas anteriormente, voc\u00ea configurou a entrega exatamente uma vez. Parab\u00e9ns!<\/p>\n<p><\/p>\n<p>Mas h\u00e1 mais um detalhe. O transactional.id que configuramos acima \u00e9, na verdade, um prefixo da transa\u00e7\u00e3o. Ao gerenciador de transa\u00e7\u00f5es, um n\u00famero sequencial \u00e9 adicionado a ele. O identificador resultante \u00e9 gerado em <strong>transactional.id.expiration.ms<\/strong>, que \u00e9 configurado em um cluster Kafka e tem como valor padr\u00e3o \"7 dias\". Se durante esse tempo o aplicativo n\u00e3o recebeu mensagens, ao tentar a pr\u00f3xima transmiss\u00e3o transacional, voc\u00ea receber\u00e1 <strong>InvalidPidMappingException<\/strong>. Ap\u00f3s isso, o coordenador de transa\u00e7\u00f5es emitir\u00e1 um novo n\u00famero sequencial para a pr\u00f3xima transa\u00e7\u00e3o. Nesse caso, a mensagem pode ser perdida se a InvalidPidMappingException n\u00e3o for tratada corretamente. <\/p>\n<p><\/p>\n<h2 id=\"vmesto-itogov\">Em vez de resultados<\/h2>\n<p><\/p>\n<p>Como voc\u00ea pode notar, n\u00e3o \u00e9 suficiente apenas enviar mensagens para o Kafka. \u00c9 preciso escolher uma combina\u00e7\u00e3o de par\u00e2metros e estar preparado para fazer altera\u00e7\u00f5es r\u00e1pidas. Neste artigo, procurei mostrar em detalhes a configura\u00e7\u00e3o de entrega exactly once e descrevi alguns problemas de configura\u00e7\u00e3o do client.id e transactional.id que enfrentamos. Abaixo est\u00e3o as configura\u00e7\u00f5es do Producer e do Consumer resumidas.<\/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 para envio ordenado)<\/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>Para minimizar erros em futuros aplicativos, fizemos nossa pr\u00f3pria camada sobre a configura\u00e7\u00e3o do spring, onde j\u00e1 est\u00e3o definidos os valores para alguns dos par\u00e2metros mencionados.<\/p>\n<p><\/p>\n<p>Aqui est\u00e3o alguns materiais para estudo independente:<\/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\">Descri\u00e7\u00e3o das configura\u00e7\u00f5es <\/a><\/noindex><\/li>\n<\/ul>\n<p>Fonte: <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.3 - 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\/pt\/blog\/administrirovanie\/kak-kafka-stala-bylyu\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"pt_PT\" \/>\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\/pt\/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\udd47 Como a Kafka se tornou realidade | ProHoster","description":"Ol\u00e1, Habr! Eu trabalho na equipe Tinkoff.","canonical_url":"https:\/\/prohoster.info\/pt\/blog\/administrirovanie\/kak-kafka-stala-bylyu","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pt_PT","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\/pt\/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\/pt\/wp-json\/wp\/v2\/posts\/54431","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/comments?post=54431"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/posts\/54431\/revisions"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/media?parent=54431"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/categories?post=54431"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pt\/wp-json\/wp\/v2\/tags?post=54431"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}