<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Thiago José de Andrade Alvoravel</title>
    <description>The latest articles on DEV Community by Thiago José de Andrade Alvoravel (@thiagoalvoravel).</description>
    <link>https://dev.to/thiagoalvoravel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3652423%2F3d7547f1-3b3b-491f-957a-85313b7e1ff2.png</url>
      <title>DEV Community: Thiago José de Andrade Alvoravel</title>
      <link>https://dev.to/thiagoalvoravel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/thiagoalvoravel"/>
    <language>en</language>
    <item>
      <title>Mensageria com RabbitMQ e Golang - Conceitos e Primeiro Contato</title>
      <dc:creator>Thiago José de Andrade Alvoravel</dc:creator>
      <pubDate>Wed, 10 Dec 2025 13:05:39 +0000</pubDate>
      <link>https://dev.to/thiagoalvoravel/mensageria-com-rabbitmq-e-golang-conceitos-e-primeiro-contato-383b</link>
      <guid>https://dev.to/thiagoalvoravel/mensageria-com-rabbitmq-e-golang-conceitos-e-primeiro-contato-383b</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;A comunicação entre sistemas mudou bastante nos últimos anos. Antes, era comum que uma aplicação chamasse outra diretamente e esperasse sua resposta. Isso funcionava, mas só até certo ponto. Quanto maior o sistema, maior o acoplamento e menor a tolerância a falhas. Hoje, quando falamos em microsserviços, escalabilidade e resiliência, surge uma alternativa que atende diversos cenários: a mensageria.&lt;/p&gt;

&lt;p&gt;A ideia central é simples. Em vez de depender de uma resposta imediata, o serviço envia uma mensagem para uma fila e segue sua vida. Outro serviço, quando puder, lê essa mensagem e faz o trabalho necessário. Isso torna a aplicação mais leve, mais modular e mais preparada para lidar com períodos de carga alta.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos entender o básico sobre mensageria, aprender como usar o RabbitMQ para organizar o fluxo de mensagens e criar exemplos práticos em Go.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que é Mensageria e por que ela é tão útil
&lt;/h2&gt;

&lt;p&gt;Mensageria é o padrão de comunicação onde sistemas conversam através do envio e consumo de mensagens, e não por chamadas diretas. Isso resolve alguns problemas comuns em arquiteturas tradicionais.&lt;/p&gt;

&lt;p&gt;Imagine um serviço de API que precisa realizar diversas etapas a partir de uma única requisição, sendo que uma delas (ou mais) pode sofrer com lentidão devido a conexão instável, grande volume de dados ou processamento mais pesado. Se for feito de forma síncrona, basta um desses passos ficar lento para o serviço todo travar, ou até mesmo ocasionar em erros.&lt;/p&gt;

&lt;p&gt;A mensageria permite deslocar essas tarefas para outro componente. Assim, a API recebe a requisição, separa o que precisa ser feito naquele momento (processamento síncrono) e o que não precisa ser concluído antes do retorno da API (processamento assíncrono). &lt;/p&gt;

&lt;p&gt;Por exemplo, se houver a necessidade dessa requisição enviar um email ao final, a API pode retornar uma mensagem informando que o email será enviado, e designar o disparo desse email a um serviço de mensageria e que será feito de forma independente.&lt;/p&gt;

&lt;p&gt;Uma cenário comum desse exemplo seria o enviar o e-mail de boas-vindas após um cadastro. Ao invés de ser feito de forma assíncrona na requisição, pode ser criada uma estrutura similar a esta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mensagem:
{
  "usuario_id": 123,
  "acao": "enviar_email_boas_vindas"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso vai para uma fila de mensagens. Depois, um outro serviço lê essa fila e manda o e-mail.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que é RabbitMQ e como ele funciona
&lt;/h2&gt;

&lt;p&gt;RabbitMQ é um message broker. Ele recebe mensagens, organiza essas mensagens em filas e garante que consumidores possam acessá-las com segurança. RabbitMQ implementa o protocolo AMQP, que define regras claras para envio, roteamento e entrega de mensagens.&lt;/p&gt;

&lt;p&gt;O RabbitMQ se destaca pela simplicidade, estabilidade e pela facilidade de adaptação a diferentes cenários — desde pequenas aplicações até sistemas de alta disponibilidade. Dentre alternativas conhecidas estão Kafka, Redis Streams e SQS.&lt;/p&gt;

&lt;p&gt;Alguns elementos básicos e fundamentais do RabbitMQ são:&lt;br&gt;
• &lt;strong&gt;Produtor (Producer)&lt;/strong&gt;: Quem envia a mensagem&lt;br&gt;
• &lt;strong&gt;Consumidor (Consumer)&lt;/strong&gt;: Quem lê e processa a mensagem&lt;br&gt;
• &lt;strong&gt;Exchange&lt;/strong&gt;: Recebe a mensagen e a redireciona&lt;br&gt;
• &lt;strong&gt;Fila (Queue)&lt;/strong&gt;: Onde a mensagem fica armazenada&lt;br&gt;
• &lt;strong&gt;Binding&lt;/strong&gt;: Associação, ou vínculo, entre uma exchange e uma fila&lt;br&gt;
• &lt;strong&gt;Routing key&lt;/strong&gt;: Chave usada para auxiliar no roteamento&lt;/p&gt;

&lt;p&gt;O Exchange é a entidade na qual o Produtor publica mensagens, que são então roteadas para um conjunto de Filas. O objetivo do Exchange é encaminhar todas as mensagens que passam por ele para uma ou mais Filas ou outros Exchanges. O tipo de Exchange e as propriedades do Binding são usados ​​para implementar a lógica de roteamento.&lt;/p&gt;

&lt;p&gt;Uma Fila no RabbitMQ é uma coleção ordenada de mensagens. As mensagens são enfileiradas (criadas pelo Produtor) e desenfileiradas (entregues aos Consumidores) de maneira FIFO ("primeiro a entrar, primeiro a sair").&lt;/p&gt;


&lt;h2&gt;
  
  
  Exemplo 1 - Conectando ao RabbitMQ com Go
&lt;/h2&gt;

&lt;p&gt;Esse artigo não tem como foco ensinar Go, ou apresentar a linguagem para quem não a conhece. Ou seja, não irei detalhar a estrutura de um projeto em Go, arquivos de configuração, dependências ou similares. Parto do princípio que se você quiser replicar os códigos mostrados aqui, saberá como criar uma estrutura básica para executar o código. &lt;/p&gt;

&lt;p&gt;Também não irei entrar em detalhes de como instalar RabbitMQ e Go, afinal existem diferentes maneiras de como você pode querer fazer (Linux, Mac, Windows, Docker, etc), para isso recomendo os links abaixo das documentações oficiais. Após instalar ambos, podemos dar continuidade:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RabbitMQ: &lt;a href="https://www.rabbitmq.com/docs/download" rel="noopener noreferrer"&gt;https://www.rabbitmq.com/docs/download&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Go: &lt;a href="https://go.dev/doc/install" rel="noopener noreferrer"&gt;https://go.dev/doc/install&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vamos começar criando um projeto em Go. O comando abaixo irá criar o(s) arquivo(s) necessário(s) dentro da pasta que você o executar:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go mod init exemplo/mensageria&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Próximo passo é criar um arquivo (fiz um chamado &lt;code&gt;teste.go&lt;/code&gt;) e colar o código abaixo. Esse exemplo é algo simples, que apenas abre uma conexão com o RabbitMQ e garante que está funcionando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "log"

    amqp "github.com/rabbitmq/amqp091-go"
)

func main() {
    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    if err != nil {
        log.Fatalf("Erro ao conectar: %s", err)
    }
    defer conn.Close()

    log.Println("Conexão bem-sucedida com RabbitMQ!")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Como criamos o projeto agora, precisamos baixar as dependências e depois executar o código. Para isso devemos executar os comandos abaixo dentro da pasta do projeto, que foi criada anteriormente:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go get&lt;/code&gt;&lt;br&gt;
&lt;code&gt;go run .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Se o serviço do RabbitMQ estiver rodando, teremos a mensagem de sucesso no log:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwd5dimbbesu7kltujcz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwd5dimbbesu7kltujcz.png" alt=" " width="390" height="38"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Certifique-se de utilizar os parâmetros corretos para conectar ao RabbitMQ pela função &lt;code&gt;amqp.Dial("amqp://guest:guest@localhost:5672")&lt;/code&gt;, caso você tenha mudado algum durante ou após a instalação, onde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;amqp - Protocolo usado pelo RabbitMQ. AMQP é o default e mais moderno&lt;/li&gt;
&lt;li&gt;guest:guest - Usuário e senha do RabbitMQ. Valores usados são os default&lt;/li&gt;
&lt;li&gt;localhost - URL de hospedagem do serviço RabbitMQ, nesse caso local&lt;/li&gt;
&lt;li&gt;5672 - Porta usada pelo serviço RabbitMQ, também é usado um valor default aqui&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Exemplo 2 - Produção e Consumo de uma Mensagem
&lt;/h2&gt;

&lt;p&gt;Agora vamos para um exemplo mais próximo da realidade: criar um produtor, que irá criar uma mensagem e colocá-la em uma fila, e um consumidor para ler essa mensagem e exibir uma mensagem no log da aplicação.&lt;/p&gt;

&lt;p&gt;Para isso teremos 2 pastas diferentes, para simular um cenário onde existem 2 aplicações distintas e que são executadas de forma independente. Podemos repetir o passo do exemplo anterior para criar a estrutura, além de aproveitar também o código usado para conexão com o serviço do RabbitMQ. Lembrando de rodar os comandos abaixo em pastas diferentes e preferencialmente, para facilitar a localização, no mesmo nível de hierarquia de pastas:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;go mod init exemplo/produtor&lt;/code&gt;&lt;br&gt;
&lt;code&gt;go mod init exemplo/consumidor&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Novamente, seguindo os passos do exemplo anterior, dentro de cada projeto vamos criar um arquivo com o código Go. Abaixo está o código completo do produtor, o qual explicarei algumas partes na sequência:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "context"
    "encoding/json"
    "log"
    "time"

    amqp "github.com/rabbitmq/amqp091-go"
)

func failOnError(err error, msg string) {
    if err != nil {
        log.Panicf("%s: %s", msg, err)
    }
}

type User struct {
    UserType int    `json:"user_type"`
    Id       int    `json:"id"`
    Name     string `json:"name"`
}

func main() {
    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    failOnError(err, "Failed to connect to RabbitMQ")
    defer conn.Close()

    ch, err := conn.Channel()
    failOnError(err, "Failed to open a channel")
    defer ch.Close()

    err = ch.ExchangeDeclare(
        "my_topic", // name
        "topic",    // type
        true,       // durable
        false,      // auto-deleted
        false,      // internal
        false,      // no-wait
        nil,        // arguments
    )
    failOnError(err, "Failed to declare an exchange")

    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()

    user1 := User{
        UserType: 1,
        Id:       10,
        Name:     "Paulo",
    }
    user1Json, _ := json.Marshal(user1)

    user2 := User{
        UserType: 2,
        Id:       20,
        Name:     "Maria",
    }
    user2Json, _ := json.Marshal(user2)

    // Envio de json
    err = ch.PublishWithContext(ctx,
        "my_topic", // exchange
        "type_1",   // routing key
        false,      // mandatory
        false,      // immediate
        amqp.Publishing{
            ContentType:  "application/json",
            Body:         []byte(user1Json),
        })

    failOnError(err, "Failed to publish a message for User 1")
    log.Printf(" [x] Sent %s\n", user1Json)

    err = ch.PublishWithContext(ctx,
        "my_topic", // exchange
        "type_2",   // routing key
        false,      // mandatory
        false,      // immediate
        amqp.Publishing{
            ContentType:  "application/json",
            Body:         []byte(user2Json),
        })

    failOnError(err, "Failed to publish a message for User 2")
    log.Printf(" [x] Sent %s\n", user2Json)
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O primeiro ponto é entender, de forma macro, o que esse código faz. Há uma struct chamada &lt;code&gt;User&lt;/code&gt; com 3 campos: &lt;code&gt;UserType&lt;/code&gt;, &lt;code&gt;Id&lt;/code&gt; e &lt;code&gt;Name&lt;/code&gt;. Nosso produtor irá instanciar variáveis do tipo &lt;code&gt;User&lt;/code&gt; e, para cada variável, produzir uma mensagem no nosso serviço do RabbitMQ. Ao longo do código há também algumas checagens para analisar se houveram erros em diferentes etapas (conectar com RabbitMQ, declarar uma Exchange, publicar uma mensagem, etc). Vamos ver alguns trechos referente à produção da mensagem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;err = ch.ExchangeDeclare(
    "my_topic", // name
    "topic",    // type
    true,       // durable
    false,      // auto-deleted
    false,      // internal
    false,      // no-wait
    nil,        // arguments
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função &lt;code&gt;ExchangeDeclare()&lt;/code&gt; irá criar uma Exchange com o nome &lt;code&gt;my_topic&lt;/code&gt;. Caso já exista uma com esse nome, é verificado se ambas possuem os mesmos parâmetros e, se sim, ela é utilizada ao invés de criar uma duplicata. &lt;/p&gt;

&lt;p&gt;O tipo da Exchange foi declarado como &lt;code&gt;topic&lt;/code&gt;. &lt;a href="https://www.rabbitmq.com/docs/exchanges#types" rel="noopener noreferrer"&gt;Existem diferentes tipos&lt;/a&gt;, cada um com sua distinção e contextos mais adequados para uso. O tipo &lt;code&gt;topic&lt;/code&gt; permite que possamos fazer o vínculo dessa mensagem com uma &lt;code&gt;routing key&lt;/code&gt; ao produzir uma mensagem. Isso é útil, pois podemos produzir mensagens dentro de uma mesma Fila e Exchange, mas separá-las por &lt;code&gt;routing key&lt;/code&gt; diferentes e as ler por diferentes consumidores (ou pelo mesmo consumidor em situações diferentes). &lt;/p&gt;

&lt;p&gt;Por exemplo, estamos produzindo mensagens com 2 usuários, cada um com o &lt;code&gt;UserType&lt;/code&gt; diferente. Podemos querer/precisar aplicar lógicas diferentes para cada tipo. Usar uma &lt;code&gt;routing key&lt;/code&gt; diferente para cada &lt;code&gt;UserType&lt;/code&gt; permite que a implementação fique mais desacoplada no consumidor, usando a mesma Exchange e Fila já que estamos criando um usuário em ambos os casos. Veremos isso na prática mais a frente.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;durable&lt;/code&gt; true e &lt;code&gt;auto-deleted&lt;/code&gt; false permitem que a Exchange continue existindo mesmo após o servidor do RabbitMQ for reiniciado e também quando não houverem mais Filas vinculadas a ela. &lt;code&gt;internal&lt;/code&gt; false não permite que a Exchange aceite mensagens publicadas para ela. Mais útil para contextos onde a Exchange será para uso interno ou privado, não ficando pública/visível para usuários do serviço. &lt;code&gt;no-wait&lt;/code&gt; true Permite criar a Exchange sem esperar a confirmação do servidor se a mesma foi criada com sucesso (no exemplo deixamos como false, pois queremos o retorno do servidor). &lt;code&gt;arguments&lt;/code&gt; permite o envio de parâmetros adicionais e opcionais, geralmente usado quando o tipo da Exchange demanda essas informações.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;err = ch.PublishWithContext(ctx,
        "my_topic", // exchange
        "type_1",   // routing key
        false,      // mandatory
        false,      // immediate
        amqp.Publishing{
            ContentType:  "application/json",
            Body:         []byte(user1Json),
        })
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A função &lt;code&gt;PublishWithContext()&lt;/code&gt; vai ser responsável por publicar a mensagem no servidor do RabbitMQ. O parâmetro &lt;code&gt;exchange&lt;/code&gt; informa o nome da Exchange, que criamos anteriormente. &lt;code&gt;routing key&lt;/code&gt; é a chave que vai vincular a mensagem publicada com a Exchange informada. Se o parâmetro &lt;code&gt;mandatory&lt;/code&gt; for true, a mensagem não será entregue ao RabbitMQ caso não haja uma Fila para consumí-la. O campo &lt;code&gt;immediate&lt;/code&gt; tem o mesmo propósito do &lt;code&gt;mandatory&lt;/code&gt;, mas funciona para caso não haja um consumidor associado a uma Fila que corresponda a essa mensagem. &lt;code&gt;ContentType&lt;/code&gt; informa a estrutura de dados que vai ser usada no conteúdo da mensagem, que no nosso caso é uma instância da struct &lt;code&gt;User&lt;/code&gt; convertida para json. &lt;code&gt;Body&lt;/code&gt; são os dados em si que serão enviados.&lt;/p&gt;

&lt;p&gt;Foram publicadas 2 mensagens na mesma Exchange, cada uma &lt;code&gt;routing key&lt;/code&gt; diferente: &lt;code&gt;type_1&lt;/code&gt; e &lt;code&gt;type_2&lt;/code&gt;. No código do consumidor veremos que mesmo na mesma Exchange e Fila, podemos consumir apenas uma &lt;code&gt;routing key&lt;/code&gt; ou ambas. Também são exibidas mensagens no log após a publicação de cada mensagem:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flps93pu2rep6sai3w202.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flps93pu2rep6sai3w202.png" alt=" " width="492" height="44"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vamos agora ao código do consumidor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
    "encoding/json"
    "log"

    amqp "github.com/rabbitmq/amqp091-go"
)

func failOnError(err error, msg string) {
    if err != nil {
        log.Panicf("%s: %s", msg, err)
    }
}

type User struct {
    UserType int    `json:"user_type"`
    Id       int    `json:"id"`
    Name     string `json:"name"`
}

func main() {
    conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")
    failOnError(err, "Failed to connect to RabbitMQ")
    defer conn.Close()

    ch, err := conn.Channel()
    failOnError(err, "Failed to open a channel")
    defer ch.Close()

    err = ch.ExchangeDeclare(
        "my_topic", // name
        "topic",    // type
        true,       // durable
        false,      // auto-deleted
        false,      // internal
        false,      // no-wait
        nil,        // arguments
    )
    failOnError(err, "Failed to declare an exchange")

    q, err := ch.QueueDeclare(
        "my_topic", // name
        true,       // durable
        false,      // auto-deleted
        false,      // exclusive
        false,      // no-wait
        nil,        // arguments
    )
    failOnError(err, "Failed to declare a queue")

    log.Printf(" [*] Queue name: %s", q.Name)

    err = ch.QueueBind(
        q.Name,     // queue name
        "type_1",   // routing key
        "my_topic", // exchange
        false,      // no-wait
        nil,        // arguments
    )
    failOnError(err, "Failed to bind a queue")

    log.Printf(" [*] Waiting for messages. To exit press CTRL+C")

    msgs, err := ch.Consume(
        q.Name, // queue
        "",     // consumer
        true,   // auto-ack
        false,  // exclusive
        false,  // no-local
        false,  // no-wait
        nil,    // args
    )
    failOnError(err, "Failed to register a consumer")

    log.Printf(" [*] Reading message")

    for d := range msgs {
        var user User
        json.Unmarshal(d.Body, &amp;amp;user)
        log.Printf("Received a message in queue %s: %v", q.Name, user)
    }

    ch.Close()
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O início do código é similar ao do produtor: definição da mesma struct usada, estabelecimento de conexão com o serviço do RabbitMQ e declaração da Exchange. Em seguida temos a declaração da Fila:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;q, err := ch.QueueDeclare(
    "my_topic", // name
    true,       // durable
    false,      // auto-deleted
    false,      // exclusive
    false,      // no-wait
    nil,        // arguments
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nossa Fila foi criada com o mesmo &lt;code&gt;name&lt;/code&gt; que a Exchange, e também com os mesmos valores para os parâmetros &lt;code&gt;durable&lt;/code&gt;, &lt;code&gt;auto-deleted&lt;/code&gt;, &lt;code&gt;no-wait&lt;/code&gt; e &lt;code&gt;arguments&lt;/code&gt; já que servem para os mesmos propósitos. O campo &lt;code&gt;exclusive&lt;/code&gt;, se for true, serve para informar se a Fila será acessível apenas pela conexão que a criou e irá deletar a Fila quando essa mesma conexão for fechada, que fazemos ao final do código com a função &lt;code&gt;Close()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Seguindo para o próximo trecho, temos a função &lt;code&gt;QueueBind()&lt;/code&gt;. Ela é responsável por vincular a Fila que criamos com a Exchange declarada anteriormente. Essa mesma Exchange foi criada no código do produtor (caso o mesmo seja executado primeiro) e, como foi explicado na parte do código do produtor, por ela ainda existir no serviço do RabbitMQ será reutilizada aqui:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;err = ch.QueueBind(
    q.Name,     // queue name
    "type_1",   // routing key
    "my_topic", // exchange
    false,      // no-wait
    nil,        // arguments
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Os parâmetros &lt;code&gt;no-wait&lt;/code&gt; e &lt;code&gt;arguments&lt;/code&gt; têm a mesma lógica já vista anteriormente. &lt;code&gt;queue name&lt;/code&gt; e &lt;code&gt;exchange&lt;/code&gt; correspondem aos nomes da Fila e Exchange, respectivamente. O parâmetro &lt;code&gt;routing key&lt;/code&gt; indica qual chave, que foi usada ao produzir a mensagem para a Exchange, iremos vincular a nossa Fila. &lt;/p&gt;

&lt;p&gt;Voltando ao código do produtor, vemos que 2 mensagens foram criadas: uma com a &lt;code&gt;routing key = "type_1"&lt;/code&gt; e outra com &lt;code&gt;routing key = "type_2"&lt;/code&gt;. Ou seja, aqui nossa Fila está vinculada apenas com a &lt;code&gt;routing key = "type_1"&lt;/code&gt; e iremos consumir apenas as mensagens da Exchange &lt;code&gt;my_topic&lt;/code&gt; que usaram essa &lt;code&gt;routing key&lt;/code&gt;. A mensagem que produzimos com a &lt;code&gt;routing key = "type_2"&lt;/code&gt; ficará na Exchange sem nenhuma Fila para consumí-la nesse momento.&lt;/p&gt;

&lt;p&gt;Por fim temos o último trecho para analisar. A função &lt;code&gt;Consume()&lt;/code&gt;, que é responsável por consumir as mensagens da Fila que criamos e vinculamos com a Exchange:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;msgs, err := ch.Consume(
    q.Name, // queue
    "",     // consumer
    true,   // auto-ack
    false,  // exclusive
    false,  // no-local
    false,  // no-wait
    nil,    // args
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;O parâmetro &lt;code&gt;queue&lt;/code&gt; informa o nome da Fila. O &lt;code&gt;consumer&lt;/code&gt; serve para atribuir uma tag (ou identificador) ao consumidor da Fila, que estamos criando. &lt;code&gt;exclusive&lt;/code&gt; quando true serve para informar ao servidor que somente este consumidor irá acessar esta Fila. &lt;code&gt;no-local&lt;/code&gt; é um parâmetro existente no protocolo AMQP, porém o RabbitMQ &lt;a href="https://www.rabbitmq.com/docs/specification#methods" rel="noopener noreferrer"&gt;não dá suporte ao mesmo&lt;/a&gt;, portanto o valor é ignorado. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;auto-ack&lt;/code&gt; true serve para informar ao serviço do RabbitMQ, de modo automático, que a mensagem foi entregue ao consumidor. Isso faz com que ela seja removida da Fila de mensagem no momento que o consumidor a lê. A depender do contexto, isso pode gerar problemas. Por exemplo, o serviço de envio de email ficou fora do ar no meio do processamento. Nesse caso a mensagem será removida da Fila sem que possamos enviar o email. Uma solução seria deixar parâmetro como false e, após processar com sucesso tudo que for necessário, informar manualmente ao servidor que a mensagem foi entregue e ela já pode ser apagada da Fila.&lt;/p&gt;

&lt;p&gt;Após declarar o consumidor, temos um loop para exibir no log os dados do usuário que foram publicados na Fila. Ao executar esse código devemos ter uma saída similar a esta:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmsojwqccq3wbzgm969b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmsojwqccq3wbzgm969b.png" alt=" " width="520" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note que foi exibido apenas os dados do usuário Paulo. Isso porque a outra mensagem, com os dados da usuária Maria, foi publicada com a &lt;code&gt;routing key = "type_2"&lt;/code&gt; e a Fila que criamos foi vinculada a &lt;code&gt;routing key = "type_1"&lt;/code&gt;. Se quisermos consumir essa outra mensagem, poderíamos ter um outro consumidor com outra Fila vinculada a ela, ou então criar um outro &lt;code&gt;QueueBind&lt;/code&gt; com a mesma Fila mudando o &lt;code&gt;routing key&lt;/code&gt;. Assim o nosso consumidor conseguiria ler mensagens de ambos os &lt;code&gt;routing key&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Nesse texto vimos uma introdução à mensageria, entendemos como funciona o RabbitMQ e como integrar ele com Go. Apesar de não ser possível abordar todas as combinações e funcionalidades que ambos oferecem, pudemos constatar que essa combinação atende bem a diversos contextos e diferentes cenários.&lt;/p&gt;




&lt;h2&gt;
  
  
  Referências
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rabbitmq.com/tutorials/tutorial-one-go" rel="noopener noreferrer"&gt;https://www.rabbitmq.com/tutorials/tutorial-one-go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rabbitmq.com/docs/use-rabbitmq" rel="noopener noreferrer"&gt;https://www.rabbitmq.com/docs/use-rabbitmq&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.algaworks.com/mensageria/" rel="noopener noreferrer"&gt;https://blog.algaworks.com/mensageria/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.sensedia.com.br/post/o-que-e-mensageria-tudo-o-que-voce-precisa-saber" rel="noopener noreferrer"&gt;https://www.sensedia.com.br/post/o-que-e-mensageria-tudo-o-que-voce-precisa-saber&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>go</category>
      <category>microservices</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Mensageria com RabbitMQ e Golang</title>
      <dc:creator>Thiago José de Andrade Alvoravel</dc:creator>
      <pubDate>Mon, 08 Dec 2025 19:12:11 +0000</pubDate>
      <link>https://dev.to/thiagoalvoravel/mensageria-com-rabbitmq-e-golang-4pnj</link>
      <guid>https://dev.to/thiagoalvoravel/mensageria-com-rabbitmq-e-golang-4pnj</guid>
      <description>&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;A comunicação entre sistemas mudou bastante nos últimos anos. Antes, era comum que uma aplicação chamasse outra diretamente e esperasse sua resposta. Isso funcionava, mas só até certo ponto: quanto maior o sistema, maior o acoplamento e menor a tolerância a falhas. Hoje, quando falamos em microsserviços, escalabilidade e resiliência, surge uma alternativa quase sempre mais saudável: a mensageria.&lt;/p&gt;

&lt;p&gt;A ideia central é simples. Em vez de depender de resposta imediata, um serviço envia uma mensagem para uma fila e segue sua vida. Outro serviço, quando puder, lê essa mensagem e faz o trabalho necessário. Isso torna a aplicação mais leve, mais modular e mais preparada para lidar com períodos de carga alta.&lt;/p&gt;

&lt;p&gt;Neste artigo, vamos entender o básico sobre mensageria, aprender como usar o RabbitMQ para organizar o fluxo de mensagens e criar exemplos práticos em Go.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que é Mensageria e por que ela é tão útil
&lt;/h2&gt;

&lt;p&gt;Mensageria é o padrão de comunicação onde sistemas conversam através do envio e consumo de mensagens, e não por chamadas diretas. Isso resolve alguns problemas comuns em arquiteturas tradicionais.&lt;/p&gt;

&lt;p&gt;Imagine um serviço de API que precisa realizar diversas etapas a partir de uma única requisição, sendo que uma delas (ou mais) pode sofrer com lentidão devido a conexão instável, grande volume de dados ou processamento mais pesado. Se for feito de forma síncrona, basta um desses passos ficar lento para o serviço todo travar, ou até mesmo ocasionar em erros.&lt;/p&gt;

&lt;p&gt;A mensageria permite deslocar essas tarefas para outro componente. Assim, a API recebe a requisição, separa o que precisa ser feito naquele momento (processamento síncrono) e o que não precisa ser concluído antes do retorno da API (processamento assíncrono). &lt;/p&gt;

&lt;p&gt;Por exemplo, se houver a necessidade dessa requisição enviar um email ao final, a API pode retornar uma mensagem informando que o email será enviado, e designar o disparo desse email a um serviço de mensageria e que será feito de forma independente.&lt;/p&gt;

&lt;p&gt;Uma cenário comum desse exemplo seria o enviar o e-mail de boas-vindas após um cadastro. Ao invés de ser feito de forma assíncrona na requisição, pode ser criada uma estrutura similar a esta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mensagem:
{
  "usuario_id": 123,
  "acao": "enviar_email_boas_vindas"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Isso vai para uma fila de mensagens. Depois, um outro serviço lê essa fila e manda o e-mail.&lt;/p&gt;




&lt;h2&gt;
  
  
  O que é RabbitMQ e como ele funciona
&lt;/h2&gt;

&lt;p&gt;RabbitMQ é um message broker. Ele recebe mensagens, organiza essas mensagens em filas e garante que consumidores possam acessá-las com segurança. RabbitMQ implementa o protocolo AMQP, que define regras claras para envio, roteamento e entrega de mensagens.&lt;/p&gt;

&lt;p&gt;O RabbitMQ se destaca pela simplicidade, estabilidade e pela facilidade de adaptação a diferentes cenários — desde pequenas aplicações até sistemas de alta disponibilidade. Dentre alternativas conhecidas estão Kafka, Redis Streams e SQS.&lt;/p&gt;

&lt;p&gt;Alguns elementos básicos e fundamentais do RabbitMQ são:&lt;br&gt;
• &lt;strong&gt;Produtor (Producer)&lt;/strong&gt;: Quem envia a mensagem&lt;br&gt;
• &lt;strong&gt;Fila (Queue)&lt;/strong&gt;: Onde a mensagem fica armazenada&lt;br&gt;
• &lt;strong&gt;Consumidor (Consumer)&lt;/strong&gt;: Quem lê e processa a mensagem&lt;br&gt;
• &lt;strong&gt;Exchange&lt;/strong&gt;: Responsável por decidir pra onde cada mensagem vai&lt;br&gt;
• &lt;strong&gt;Binding&lt;/strong&gt;: Associação, ou vínculo, entre uma exchange e uma fila&lt;br&gt;
• &lt;strong&gt;Routing key&lt;/strong&gt;: Chave usada para auxiliar no roteamento&lt;/p&gt;

&lt;p&gt;O Exchange é a entidade na qual o Produtor publica mensagens, que são então roteadas para um conjunto de Filas. O objetivo do Exchange é encaminhar todas as mensagens que passam por ele para uma ou mais Filas ou outros Exchanges. O tipo de Exchange e as propriedades do Binding são usados ​​para implementar a lógica de roteamento.&lt;/p&gt;

&lt;p&gt;Uma Fila no RabbitMQ é uma coleção ordenada de mensagens. As mensagens são enfileiradas (criadas pelo Produtor) e desenfileiradas (entregues aos Consumidores) de maneira FIFO ("primeiro a entrar, primeiro a sair").&lt;/p&gt;

</description>
      <category>backend</category>
      <category>microservices</category>
      <category>go</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
