{"id":12484,"date":"2018-01-17T09:00:03","date_gmt":"2018-01-17T11:00:03","guid":{"rendered":"https:\/\/king.host\/blog\/?p=12484"},"modified":"2024-06-03T17:09:39","modified_gmt":"2024-06-03T20:09:39","slug":"como-gerenciar-filas-php-com-rabbitmq","status":"publish","type":"post","link":"https:\/\/king.host\/blog\/tecnologia\/como-gerenciar-filas-php-com-rabbitmq\/","title":{"rendered":"Gerenciando filas simples em PHP com RabbitMq"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">As palavras do momento s\u00e3o escalabilidade e microsservi\u00e7os! Todo mundo quer ser cool e estar por dentro das inova\u00e7\u00f5es. Pensando nisso, venho falar um pouco sobre os message brokers (envio de mensagens entre sistemas), uma das t\u00e9cnicas mais utilizadas para comunica\u00e7\u00e3o ass\u00edncrona,\u00a0utilizando o RabbitMq.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">\u00c9 legal tamb\u00e9m entender quais problemas essa t\u00e9cnica resolve e quais ele n\u00e3o resolve! Para saber justamente o que \u00e9 prego e o que \u00e9 parafuso.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">O que \u00e9 uma fila?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Uma fila \u00e9 composta por v\u00e1rias mensagens que ser\u00e3o consumidas por algu\u00e9m.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Como podemos ver em vermelho na figura 1 abaixo.<\/span><\/p>\n<figure id=\"attachment_12486\" aria-describedby=\"caption-attachment-12486\" style=\"width: 332px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-12486 size-full\" src=\"https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/1.png\" alt=\"\" width=\"332\" height=\"111\" title=\"\" srcset=\"https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/1.png 332w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/1-300x100.png 300w\" sizes=\"(max-width: 332px) 100vw, 332px\" \/><figcaption id=\"caption-attachment-12486\" class=\"wp-caption-text\">Fig 1. Fila<\/figcaption><\/figure>\n<p><span style=\"font-weight: 400;\">Como podemos observar ainda na figura 1, n\u00f3s temos o \u201cP\u201d representando o produtor de mensagens e os consumidores \u201cC\u201d (ou Workers), consumindo as mensagens dessa fila. At\u00e9 a\u00ed\u2026 tudo f\u00e1cil.<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">O que \u00e9 o RabbitMq?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">\u00c9 um servi\u00e7o de gerenciamento de filas, com ele voc\u00ea pode criar usu\u00e1rios, filas e uma gama de outras funcionalidades. Vou demonstrar aqui de forma bem simples. Para um primeiro contato apenas.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Subindo um servidor Rabbit (utilizando <strong>Docker<\/strong>):<\/span><\/p>\n<pre id=\"4c5f\" class=\"lang:Go\"><code class=\"markup--code markup--pre-code\">$ docker run -d --hostname my-rabbit --name some-rabbit -p 8080:15672 -p 5672:5672 rabbitmq:management-alpine<\/code><\/pre>\n<p><span style=\"font-weight: 400;\">Pronto, ja podemos acessar a aplica\u00e7\u00e3o (user: guest\/ pass: guest):<\/span><\/p>\n<figure id=\"attachment_12489\" aria-describedby=\"caption-attachment-12489\" style=\"width: 650px\" class=\"wp-caption aligncenter\"><img fetchpriority=\"high\" decoding=\"async\" class=\"wp-image-12489 size-full\" src=\"https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/2.png\" alt=\"\" width=\"650\" height=\"450\" title=\"\" srcset=\"https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/2.png 650w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/2-300x208.png 300w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/2-400x277.png 400w\" sizes=\"(max-width: 650px) 100vw, 650px\" \/><figcaption id=\"caption-attachment-12489\" class=\"wp-caption-text\">Fig 2. Tela Inicial RabbitMq<\/figcaption><\/figure>\n<p><span style=\"font-weight: 400;\">E j\u00e1 podemos ver o nosso servidor rodando!<\/span><\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-12490 size-large\" src=\"https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/3-780x427.png\" alt=\"\" width=\"780\" height=\"427\" title=\"\" srcset=\"https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/3-780x427.png 780w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/3-300x164.png 300w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/3-768x420.png 768w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/3-400x219.png 400w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/3.png 1000w\" sizes=\"(max-width: 780px) 100vw, 780px\" \/><\/p>\n<p><span style=\"font-weight: 400;\">Criando o primeiro Producer (Produtor de mensagens)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Vamos criar um simples script php para interagir com o nosso Rabbit, primeiro crie o arquivo composer.json com o seguinte conte\u00fado:<\/span><\/p>\n<pre id=\"cdd2\" class=\"graf graf--pre graf-after--p\">{\n    \"require\": {\n        \"php-amqplib\/php-amqplib\": \"&gt;=2.6.1\"\n    }\n}<\/pre>\n<p><span style=\"font-weight: 400;\">Instale as depend\u00eancias:<\/span><\/p>\n<pre id=\"b2bb\" class=\"lang:php\">composer.phar install<\/pre>\n<p><span style=\"font-weight: 400;\">Vamos criar o arquivo send.php com o seguinte conte\u00fado:<\/span><\/p>\n<pre class=\"\">&lt;?php\n\nrequire_once __DIR__ . '\/vendor\/autoload.php';\n\nuse PhpAmqpLib\\Connection\\AMQPStreamConnection;\nuse PhpAmqpLib\\Message\\AMQPMessage;\n\n\/**\n * Inicia a conex\u00e3o\n *\/\n$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');\n$channel = $connection-&gt;channel();\n\n\/**\n * Declara qual a fila que ser\u00e1 usada\n *\/\n$channel-&gt;queue_declare('hello', false, false, false, false);\n\n\/**\n * Cria a nova mensagem\n *\/\n$msg = new AMQPMessage('Ola mundo!');\n\n\/**\n * Envia para a fila\n *\/\n$channel-&gt;basic_publish($msg, '', 'hello');\n\n\/**\n * Encerra conex\u00e3o\n *\/\n$channel-&gt;close();\n$connection-&gt;close();<\/pre>\n<p>Logo ap\u00f3s criarmos o arquivo receive.php<\/p>\n<pre class=\"\">&lt;?php\n\nrequire_once __DIR__ . '\/vendor\/autoload.php';\n\nuse PhpAmqpLib\\Connection\\AMQPStreamConnection;\n\n\n\/**\n * Inicia a conex\u00e3o\n *\/\n$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');\n$channel = $connection-&gt;channel();\n\n\/**\n * Declara qual a fila que ser\u00e1 usada\n *\/\n$channel-&gt;queue_declare('hello', false, false, false, false);\n\necho ' [*] Waiting for messages. To exit press CTRL+C', \"\\n\";\n\n\/**\n * Fun\u00e7\u00e3o que vai receber e tratar efetivamente a mensagem\n *\/\n$callback = function($msg) {\n  echo \" [x] Received \", $msg-&gt;body, \"\\n\";\n};\n\n\/**\n * Adiciona esse \"callback\" para a fila \n *\/\n$channel-&gt;basic_consume('hello', '', false, true, false, false, $callback);\n\n\/**\n * Mantem a fun\u00e7\u00e3o escutando a fila por tempo indeterminado, at\u00e9 que seja encerrada\n *\/\nwhile(count($channel-&gt;callbacks)) {\n    $channel-&gt;wait();\n}\n\n$channel-&gt;close();\n$connection-&gt;close();<\/pre>\n<p>Rodando esses dois arquivos agora, com o nosso servidor up, podemos ver a seguinte mensagem (clique na imagem para expandir):<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-12491 size-large\" src=\"https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/imagem-5-780x132.png\" alt=\"\" width=\"780\" height=\"132\" title=\"\" srcset=\"https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/imagem-5-780x132.png 780w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/imagem-5-300x51.png 300w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/imagem-5-768x130.png 768w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/imagem-5-1024x173.png 1024w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/imagem-5-400x68.png 400w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/imagem-5-1320x224.png 1320w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/imagem-5.png 1919w\" sizes=\"(max-width: 780px) 100vw, 780px\" \/><\/p>\n<p><span style=\"font-weight: 400;\"><br \/>\nPodemos adicionar quantos \u201cworkers\u201d forem necess\u00e1rios! Veja o exemplo abaixo (clique na imagem para expandir):<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-12637 size-large\" src=\"https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/php-780x438.png\" alt=\"\" width=\"780\" height=\"438\" title=\"\" srcset=\"https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/php-780x438.png 780w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/php-300x168.png 300w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/php-768x431.png 768w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/php-1024x574.png 1024w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/php-400x224.png 400w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/php-1320x741.png 1320w, https:\/\/cdn-cms.king.host\/blog-hlg\/uploads\/2018\/01\/php.png 1918w\" sizes=\"(max-width: 780px) 100vw, 780px\" \/><\/p>\n<h2><span style=\"font-weight: 400;\">Incr\u00edvel n\u00e3o?<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">Essa tecnologia nos permite in\u00fameras possibilidades, tendo apenas 1 servidor provendo o servi\u00e7o do Rabbit. Isso significa que v\u00e1rias aplica\u00e7\u00f5es podem utilizar usu\u00e1rios diferentes e criar filas e workers conforme a sua necessidade!<\/span><\/p>\n<h2><span style=\"font-weight: 400;\">Quais os casos em que eu posso utilizar o RabbitMQ?<\/span><\/h2>\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Processos independentes: quando eu preciso realizar uma tarefa em paralelo mas n\u00e3o \u00e9 necess\u00e1rio esperar ela terminar para continuar o meu fluxo.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Envio de email: Caso comum de quando eu n\u00e3o preciso aguardar uma resposta do meu SMTP. O worker pode se encarregar disso.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Registro de logs: Com aplica\u00e7\u00f5es distribu\u00eddas em N servidores, n\u00e3o podemos e nem devemos guardar os logs localmente no servidor. Nesse cen\u00e1rio a aplica\u00e7\u00e3o A1 envia os logs para uma fila no servidor B e o worker no servidor C ir\u00e1 consumir a fila e armazenar\u00e1 corretamente esse log. Mesmo escalando minha aplica\u00e7\u00e3o para A1 A2 A3, todos os logs ser\u00e3o armazenados no local correto.<\/span><\/li>\n<\/ol>\n<h2><span style=\"font-weight: 400;\">Quando n\u00e3o usar o RabbitMQ?<\/span><\/h2>\n<ol>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Processos baseados em tempo. Ex: Essa rotina deve executar sempre \u00e0s 14h. Para esse problema existem outras formas de resolu\u00e7\u00e3o.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Grande volumes de dados: Quando eu falo em grande volume, \u00e9 GRANDE volume\u2026 um servidor m\u00ednimo do rabbit consegue dar conta de pelo menos 20.000 msg\/s. Isso vai depender de qu\u00e3o pesado \u00e9 a atividade do worker. Mas mesmo para aplica\u00e7\u00f5es que geram bastante logs, essa taxa de mensagens \u00e9 suficiente. Voc\u00ea deve pensar em outra solu\u00e7\u00e3o (ex: Kafka) se a sua necessidade excede as 300.000 msg\/s.<\/span><\/li>\n<\/ol>\n<h2><span style=\"font-weight: 400;\">Conclus\u00e3o<\/span><\/h2>\n<p><span style=\"font-weight: 400;\">O servi\u00e7o de mensagens pode ser um grande aliado na constru\u00e7\u00e3o de sistemas simples e independentes, separando responsabilidades e obrigando a cria\u00e7\u00e3o de pap\u00e9is distintos.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">O ponto forte do RabbitMQ \u00e9 a simplicidade de utiliza\u00e7\u00e3o, junto com uma interface de gerenciamento. Por outro lado \u00e9 um pouco mais custoso escalar a estrutura.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Eu j\u00e1 utilizo o Rabbit em produ\u00e7\u00e3o h\u00e1 3 anos em diversos projetos e n\u00e3o tive problemas. Aconselho todos a darem uma olhada e brincarem um pouco.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Todos os arquivos est\u00e3o mencionados no texto. Divirtam-se!<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Para mais aprendizados: vejam a documenta\u00e7\u00e3o oficial no site do <a href=\"https:\/\/www.rabbitmq.com\/getstarted.html\" target=\"_blank\" rel=\"noopener\">RabbitMQ<\/a>!<\/span><\/p>\n<p>Curtiu do material? Acompanhe outros posts meus no <a href=\"https:\/\/king.host\/blog\/author\/archer\/\" target=\"_blank\" rel=\"noopener\">blog da KingHost<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>As palavras do momento s\u00e3o escalabilidade e microsservi\u00e7os! Todo mundo quer ser cool e estar por dentro das inova\u00e7\u00f5es. Pensando nisso, venho falar um pouco sobre os message brokers (envio de mensagens entre sistemas), uma das t\u00e9cnicas mais utilizadas para comunica\u00e7\u00e3o ass\u00edncrona,\u00a0utilizando o RabbitMq. \u00c9 legal tamb\u00e9m entender quais problemas essa t\u00e9cnica resolve e quais [&hellip;]<\/p>\n","protected":false},"author":292,"featured_media":12514,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1179,8],"tags":[1374],"class_list":["post-12484","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desenvolvimento","category-tecnologia","tag-php"],"_links":{"self":[{"href":"https:\/\/king.host\/blog\/wp-json\/wp\/v2\/posts\/12484","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/king.host\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/king.host\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/king.host\/blog\/wp-json\/wp\/v2\/users\/292"}],"replies":[{"embeddable":true,"href":"https:\/\/king.host\/blog\/wp-json\/wp\/v2\/comments?post=12484"}],"version-history":[{"count":22,"href":"https:\/\/king.host\/blog\/wp-json\/wp\/v2\/posts\/12484\/revisions"}],"predecessor-version":[{"id":36417,"href":"https:\/\/king.host\/blog\/wp-json\/wp\/v2\/posts\/12484\/revisions\/36417"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/king.host\/blog\/wp-json\/wp\/v2\/media\/12514"}],"wp:attachment":[{"href":"https:\/\/king.host\/blog\/wp-json\/wp\/v2\/media?parent=12484"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/king.host\/blog\/wp-json\/wp\/v2\/categories?post=12484"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/king.host\/blog\/wp-json\/wp\/v2\/tags?post=12484"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}