RabbitMQ – Guia rápido

Saudações.

Esse tutorial é um guia rápido de instalação e uso do RabbitMQ em ambiente Docker.

Pré-requisitos (constam em outros artigos aqui do blog):

  • Instalação do Linux (Debian);
  • Internet no servidor (sua VPS ou host);
  • Docker CE instalado;

1 – Preparando o Docker

Vamos preparar o ambiente docker com a rede (network_public), o Traefik com suporte a repasse do tráfego AMQP com TLS e suporte HTTPs via LetsEncrypt.

Escolha uma das 3 formas:

  • Seção 2.1: rede com endereçamento automático;
  • Seção 2.2: rede com endereçamento IPv4 manual e MTU 65495;
  • Seção 2.3: rede com endereço IPv4+IPv6 manual e MTU 65495;

1.1 – Docker Network com endereçamento automático

Bash
docker network create \
    -d bridge \
    network_public;

1.2 – Docker Network IPv4

Bash
docker network create \
    -d bridge \
    \
    -o "com.docker.network.bridge.name"="br-net-public" \
    -o "com.docker.network.bridge.enable_icc"="true" \
    -o "com.docker.network.driver.mtu"="65495" \
    \
    --subnet 10.249.0.0/16 --gateway 10.249.255.254 \
    \
    network_public;

1.3 – Docker Network Dual Stack (IPv4 + IPv6)

Bash
docker network create \
    -d bridge \
    \
    -o "com.docker.network.bridge.name"="br-net-public" \
    -o "com.docker.network.bridge.enable_icc"="true" \
    -o "com.docker.network.driver.mtu"="65495" \
    \
    --subnet 10.249.0.0/16 --gateway 10.249.255.254 \
    --ipv6 \
    --subnet=2001:db8:10:249::/64 \
    --gateway=2001:db8:10:249::ffff \
    \
    network_public;

2 – Container do Traefik

Alterações feitas na configuração do container Traefik:

  • Redirecionamento da porta 5671/tcp do host para o container;
  • Adicionei na configuração do Traefik uma nova “entrypoint” chamada “amqps” (AMQP Seguro) nessa porta 5671/tcp;

O container do Traefik se chamará “traefik-app“.

2.1 – Email do contato LetsEncrypt

Personalize a variável EMAIL para que o LetsEncrypt funcione corretamente. Vou salvar o email de contato no arquivo /etc/email do host:

Bash
# Email de registro no letsencrypt
EMAIL="voce@seudominio.com.br";

# Gravar no arquivo para consulta
echo "$EMAIL" > /etc/email;

2.2 – Traefik com TLS offload para AMQPs

Rodando o Traefik :

Bash
#!/bin/sh

# Variaveis
  # - Nome do container
  NAME=traefik-app;
  
  # - Imagem do software traefik
  IMAGE=traefik:latest;
  
  # - Email de registro no letsencrypt
  EMAIL=$(head -1 /etc/email);

  # - Diretorio do volume (dados persistentes)
  DATADIR=/storage/$NAME;

# Preparar volume:
  mkdir -p $DATADIR/letsencrypt;
  mkdir -p $DATADIR/logs;
  mkdir -p $DATADIR/config;

# Obter imagem atualizada:
  docker pull $IMAGE;

# Remover instância atual:
  docker rm -f $NAME 2>/dev/null;

# Renovar/criar/rodar:
docker run \
    -d --restart=unless-stopped --name $NAME -h $NAME.intranet.br \
    \
    --network network_public \
    \
    -p 80:80 \
    -p 443:443 \
    -p 5671:5671 \
    \
    -v /var/run/docker.sock:/var/run/docker.sock:ro \
    -v $DATADIR/letsencrypt:/etc/letsencrypt \
    -v $DATADIR/config:/etc/traefik \
    -v $DATADIR/logs:/logs \
    \
    --tmpfs /run:rw,noexec,nosuid,size=16m \
    --tmpfs /tmp:rw,noexec,nosuid,size=16m \
    --read-only \
    \
    $IMAGE \
      \
      --global.checkNewVersion=false \
      --global.sendAnonymousUsage=false \
      \
      --api.insecure=true \
      \
      --log.level=INFO \
      --log.filePath=/logs/error.log \
      \
      --accessLog.filePath=/logs/access.log \
      \
      --entrypoints.web.address=:80 \
      --entrypoints.web.http.redirections.entryPoint.to=websecure \
      --entrypoints.web.http.redirections.entryPoint.scheme=https \
      --entrypoints.web.http.redirections.entryPoint.permanent=true \
      \
      --entrypoints.websecure.address=:443 \
      \
      --entrypoints.amqps.address=:5671 \
      \
      --providers.docker=true \
      --providers.file.directory=/etc/traefik \
      \
      --certificatesresolvers.letsencrypt.acme.email=$EMAIL \
      --certificatesresolvers.letsencrypt.acme.storage=/etc/letsencrypt/acme.json \
      --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web;

3 – Implementando RabbitMQ no Docker

Escolha uma das formas de rodar:

  • Seção 3.1: RabbitMQ puro, sem Traefik, porta de administração web com acesso direto via HTTP e porta AMQP publicada, bom para implementações rápidas;
  • Seção 3.2: RabbitMQ e Traefik simples, somente HTTPs, sem TLS no AMQP;
  • Seção 3.3: RabbitMQ e Traefik completo;

3.1 – RabbitMQ puro

Bash
# Variaveis
    # - Nome do container
    NAME="rabbitmq";
    
    # - VHOST padrão (alternativo ao "/")
    RABBITMQ_DEFAULT_VHOST="default";

    # - Troque por uma sequencia hexadecimal aleatoria: openssl rand -hex 32;
    RABBITMQ_ERLANG_COOKIE="ffffffffffffffffffffffffffffffff";

    # - Credenciais de acesso administrativo inicial
    RABBITMQ_USER="admin";
    RABBITMQ_PASS="Sua_SenhaForte@";

    # - Pasta do volume
    DATADIR=/storage/rabbitmq;

    #IMAGE=rabbitmq:management;
    IMAGE="rabbitmq:4-management";

# Criar pasta do volume
    mkdir -p $DATADIR;

# Parar container atual:
    docker rm -f $NAME 2>/dev/null;

# Criar e rodar:
    docker run -d --restart=always \
        --name $NAME --hostname $NAME.intranet.br \
        \
        --cpus=2.0 \
        --memory=2g --memory-swap=2g \
        \
        --tmpfs /run:rw,noexec,nosuid,size=32m \
        --tmpfs /tmp:rw,noexec,nosuid,size=32m \
        \
        --network network_public \
        \
        -p 5672:5672 \
        -p 15672:15672 \
        \
        -e TZ=America/Sao_Paulo \
        -e RABBITMQ_DEFAULT_VHOST=$RABBITMQ_DEFAULT_VHOST \
        -e RABBITMQ_ERLANG_COOKIE=$RABBITMQ_ERLANG_COOKIE \
        -e RABBITMQ_DEFAULT_USER=$RABBITMQ_USER \
        -e RABBITMQ_DEFAULT_PASS=$RABBITMQ_PASS \
        \
        -v $DATADIR:/var/lib/rabbitmq \
        \
        --health-cmd="rabbitmq-diagnostics check_running" \
        --health-interval=15s \
        --health-timeout=10s \
        --health-retries=5 \
        \
        $IMAGE;

    echo;
    echo "Acesso:";
    echo "Web......: http://ip-do-servidor:15672";
    echo;

3.2 – RabbitMQ e Traefik simples

Troque rabbitmq.seudominio.com.br pelo nome de DNS (FQDN) desejado:

Bash
# Variaveis
    # - Nome do container
    NAME="rabbitmq";
    
    # - Nome de DNS para acesso pelo navegador
    FQDN="rabbitmq.seudominio.com.br";

    # - Timezone para hora local
    TZ="America/Sao_Paulo";
    
    # - VHOST padrão (alternativo ao "/")
    RABBITMQ_DEFAULT_VHOST="default";

    # - Troque por uma sequencia hexadecimal aleatoria: openssl rand -hex 32;
    RABBITMQ_ERLANG_COOKIE="ffffffffffffffffffffffffffffffff";

    # - Credenciais de acesso administrativo inicial
    RABBITMQ_USER="admin";
    RABBITMQ_PASS="Sua_SenhaForte@";

    # - Pasta do volume
    DATADIR=/storage/rabbitmq;

    #IMAGE=rabbitmq:management;
    IMAGE="rabbitmq:4-management";

# Criar pasta do volume
    mkdir -p $DATADIR;

# Parar container atual:
    docker rm -f $NAME 2>/dev/null;

# Criar e rodar:
    docker run -d --restart=always \
        --name $NAME --hostname $NAME.intranet.br \
        \
        --cpus=2.0 \
        --memory=2g --memory-swap=2g \
        \
        --tmpfs /run:rw,noexec,nosuid,size=32m \
        --tmpfs /tmp:rw,noexec,nosuid,size=32m \
        \
        --network network_public \
        \
        -p 5672:5672 \
        -p 15672:15672 \
        \
        -e TZ=America/Sao_Paulo \
        -e RABBITMQ_DEFAULT_VHOST=$RABBITMQ_DEFAULT_VHOST \
        -e RABBITMQ_ERLANG_COOKIE=$RABBITMQ_ERLANG_COOKIE \
        -e RABBITMQ_DEFAULT_USER=$RABBITMQ_USER \
        -e RABBITMQ_DEFAULT_PASS=$RABBITMQ_PASS \
        \
        -v $DATADIR:/var/lib/rabbitmq \
        \
        --label "traefik.enable=true" \
        --label "traefik.http.routers.$NAME.rule=Host(\`$FQDN\`)" \
        --label "traefik.http.routers.$NAME.entrypoints=web,websecure" \
        --label "traefik.http.routers.$NAME.tls=true" \
        --label "traefik.http.routers.$NAME.tls.certresolver=letsencrypt" \
        --label "traefik.http.services.$NAME.loadbalancer.passHostHeader=true" \
        --label "traefik.http.services.$NAME.loadbalancer.server.port=15672" \
        \
        --health-cmd="rabbitmq-diagnostics check_running" \
        --health-interval=15s \
        --health-timeout=10s \
        --health-retries=5 \
        \
        $IMAGE;

    echo;
    echo "Acesso:";
    echo "Web......: https://$FQDN";
    echo;

3.3 – RabbitMQ e Traefik completo (HTTPs + AMQPs)

Obs.: Requer abertura da porta 5671 no Traefik.

Bash
# Variaveis
    # - Nome do container
    NAME="rabbitmq";
    
    # - Nome de DNS para acesso pelo navegador
    FQDN="rabbitmq.seudominio.com.br";

    # - Timezone para hora local
    TZ="America/Sao_Paulo";
    
    # - VHOST padrão (alternativo ao "/")
    RABBITMQ_DEFAULT_VHOST="default";

    # - Troque por uma sequencia hexadecimal aleatoria: openssl rand -hex 32;
    RABBITMQ_ERLANG_COOKIE="ffffffffffffffffffffffffffffffff";

    # - Credenciais de acesso administrativo inicial
    RABBITMQ_USER="admin";
    RABBITMQ_PASS="Sua_SenhaForte@";

    # - Pasta do volume
    DATADIR=/storage/rabbitmq;

    #IMAGE=rabbitmq:management;
    IMAGE="rabbitmq:4-management";

# Criar pasta do volume
    mkdir -p $DATADIR;

# Parar container atual:
    docker rm -f $NAME 2>/dev/null;

# Criar e rodar:
    docker run -d --restart=always \
        --name $NAME --hostname $NAME.intranet.br \
        \
        --cpus=2.0 \
        --memory=2g --memory-swap=2g \
        \
        --tmpfs /run:rw,noexec,nosuid,size=32m \
        --tmpfs /tmp:rw,noexec,nosuid,size=32m \
        \
        --network network_public \
        \
        -p 5672:5672 \
        -p 15672:15672 \
        \
        -e TZ=America/Sao_Paulo \
        -e RABBITMQ_DEFAULT_VHOST=$RABBITMQ_DEFAULT_VHOST \
        -e RABBITMQ_ERLANG_COOKIE=$RABBITMQ_ERLANG_COOKIE \
        -e RABBITMQ_DEFAULT_USER=$RABBITMQ_USER \
        -e RABBITMQ_DEFAULT_PASS=$RABBITMQ_PASS \
        \
        -v $DATADIR:/var/lib/rabbitmq \
        \
        --label "traefik.enable=true" \
        --label "traefik.http.routers.$NAME.rule=Host(\`$FQDN\`)" \
        --label "traefik.http.routers.$NAME.entrypoints=web,websecure" \
        --label "traefik.http.routers.$NAME.tls=true" \
        --label "traefik.http.routers.$NAME.tls.certresolver=letsencrypt" \
        --label "traefik.http.services.$NAME.loadbalancer.passHostHeader=true" \
        --label "traefik.http.services.$NAME.loadbalancer.server.port=15672" \
        \
        --label "traefik.tcp.routers.$NAME-amqp.entrypoints=amqps" \
        --label "traefik.tcp.routers.$NAME-amqp.rule=HostSNI(\`$FQDN\`)" \
        --label "traefik.tcp.routers.$NAME-amqp.tls=true" \
        --label "traefik.tcp.routers.$NAME-amqp.tls.certresolver=letsencrypt" \
        --label "traefik.tcp.services.$NAME-amqp.loadbalancer.server.port=5672" \
        \
        --health-cmd="rabbitmq-diagnostics check_running" \
        --health-interval=15s \
        --health-timeout=10s \
        --health-retries=5 \
        \
        $IMAGE;

    echo;
    echo "Acesso:";
    echo "Web......: https://$FQDN";
    echo "AMQPs....: tls://$FQDN:5671";
    echo;

3.4 – Ajustes pós-instalação

É muito importante remover o usuário guest por segurança:

Bash
# Remover usuario guest:
docker exec rabbitmq rabbitmqctl delete_user guest;

3.5 – Primeiro contato

Alterando a senha do usuário admin e garantindo privilégios:

Bash
# Alterar senha do admin:
docker exec rabbitmq rabbitmqctl change_password admin 'Sua_SenhaForte@';

# Garantir (reafirmar) poderes ao admin:
docker exec rabbitmq rabbitmqctl set_user_tags    admin  administrator;
docker exec rabbitmq rabbitmqctl set_permissions  -p default admin ".*" ".*" ".*";

# Listar usuários:
docker exec rabbitmq rabbitmqctl list_users;

Criar o usuário suporte com poderes administrativos:

Bash
# Adicionar usuario suporte com todos os poderes de admin:
docker exec rabbitmq rabbitmqctl add_user        suporte  'Sua_SenhaForte@';    
docker exec rabbitmq rabbitmqctl set_user_tags   suporte  administrator;
docker exec rabbitmq rabbitmqctl set_permissions -p default suporte ".*" ".*" ".*";

# Listar usuários:
docker exec rabbitmq rabbitmqctl list_users;

Controle do serviço:

Bash
# Parar aplicação RabbitMQ (mantém Erlang VM):
docker exec rabbitmq rabbitmqctl stop_app;

# Iniciar aplicação RabbitMQ:
docker exec rabbitmq rabbitmqctl start_app;

# Resetar node (remove dados):
docker exec rabbitmq rabbitmqctl reset;

# Forçar reset:
docker exec rabbitmq rabbitmqctl force_reset;

Listar usuários e objetos no VHOST “default“:

Bash
# Listar usuários:
docker exec rabbitmq rabbitmqctl list_users;

# Listar/Verificar exchanges no VHOST
docker exec rabbitmq rabbitmqctl list_exchanges -p default;

# Listar/Verificar filas no VHOST
docker exec rabbitmq rabbitmqctl list_queues    -p default;

# Listar/Verificar bindings no VHOST
docker exec rabbitmq rabbitmqctl list_bindings  -p default;

# Listar/Verificar canais ativos:
docker exec rabbitmq rabbitmqctl list_channels  -p default;

3.6 – Primeiro acesso web

O RabbitMQ pode ser totalmente administrado pela interface web!

Acesse:

  • Pelo nome de DNS configurado para o servidor (https:// + nome) ou
  • Pela porta HTTP 15672 (http:// + ip ou nome + :15672);

Gerencia web:

Tela de login

Após logar, a interface web permite a criação de objetos (VHOSTs, exchanges, bindings, filas, novos usuários, controle de privilégio, logs, estatísticas, etc).

Tela inicial da administração web (tema escuro, use o ícone do canto inferior direito para alternar).

4 – Comandos básicos de terminal

Esse capítulo aborda as operações de administração do MQ por meio do shell (terminal).

Se você estiver no terminal do servidor utilize sempre “docker exec“.
Se estiver no shell dentro do container inicie os comandos em “rabbitmqctl …“.

Para entrar no terminal do container rabbitmq, execute:

Bash
# Entrar no shell do container rabbitmq:
docker exec -it rabbitmq bash;

# Apos entrar:
# Testando shell do container:
rabbitmqctl ping;

4.1 – Status do ambiente

Esses comandos visam verificar se o RabbitMQ está rodando e operacional:

Bash
# Comandos básicos
# Status geral
rabbitmqctl status;      # Status do serviço:
rabbitmqctl ping;        # Teste de funcionamento
rabbitmqctl environment; # Informações detalhadas

# Listar filas
rabbitmqctl list_queues;

# Listar exchanges
rabbitmqctl list_exchanges;

# Listar conexões
rabbitmqctl list_connections;

# Listar usuários
rabbitmqctl list_users;

# Conferir permissões do usuário
rabbitmqctl list_user_permissions admin;
rabbitmqctl list_user_permissions suporte;

# Listar plugins habilitados
rabbitmq-plugins list --enabled;

# Health check manual
rabbitmq-diagnostics -q ping;

# Habilitar um plugin
#- rabbitmq-plugins enable <nome_do_plugin>;

4.2 – Gestão de usuários

Bash
# Comandos básicos de gestão de usuários:
# Listar usuários
rabbitmqctl list_users;

# Adicionar usuário
rabbitmqctl add_user        user01  tulipa;

# Alterar senha do usuário
rabbitmqctl change_password user01  javali;

# Definir tag no usuário (administrator = super-poderes):
rabbitmqctl set_user_tags   user01  administrator; 

# Conferir permissões do usuário
rabbitmqctl list_user_permissions user01;

# Retirar todas as permissões do usuário:
rabbitmqctl clear_permissions -p user01 operador;

# Definir permissões de um usuario no VHOST 'default' (configure, write, read)
rabbitmqctl set_permissions -p default user01 ".*" ".*" ".*";

# Deletar usuário:
rabbitmqctl delete_user  user01;

4.3 – Gestão de Virtual Host (VHOST)

Vou criar um VHOST chamado “vsite” e o usuário “vsite_admin” com poderes para administrar somente objetos nele:

Bash
# Gerenciamento de Virtual Host (VHOST):

# Criar vhost (virtual host):
rabbitmqctl add_vhost    vsite;

# Listar virtual hosts
rabbitmqctl list_vhosts;

# Adicionar usuário para uso exclusivo no VHOST vsite:
rabbitmqctl add_user                    vsite_admin  tulipa;
rabbitmqctl set_permissions   -p vsite  vsite_admin  ".*" ".*" ".*";
rabbitmqctl list_user_permissions       vsite_admin;

# Tag management: acesso a UI/API restrito ao VHOST vsite:
rabbitmqctl set_user_tags               vsite_admin;
rabbitmqctl set_user_tags               vsite_admin  management;

# Listar tudo:
rabbitmqctl list_vhosts;
rabbitmqctl list_users;

# Remover vhost:
#- rabbitmqctl delete_vhost vsite;

# Remover usuario administrador do vhost:
#- rabbitmqctl delete_user  vsite_admin;

4.4 – Gestão de Exchanges

Vou realizar as operações de demonstração no VHOST “vsite” criado na seção 4.3:

Bash
# Listagem
# Listar/Verificar exchanges no VHOST
rabbitmqctl list_exchanges -p vsite;

# Listar/Verificar filas no VHOST
rabbitmqctl list_queues    -p vsite;

# Listar/Verificar bindings no VHOST
rabbitmqctl list_bindings  -p vsite;

# Listar/Verificar canais ativos:
rabbitmqctl list_channels  -p vsite;


# Criar exchanges
# Criar exchange tipo fanout (broadcast)
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare exchange --name inbox_fanout --type fanout --durable true;

# Criar exchange tipo direct (routing-key exata)
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare exchange --name inbox_direct --type direct --durable true;

# Criar exchange tipo topic (routing-key pattern * #)
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare exchange --name inbox_topic --type topic --durable true;

# Criar exchange tipo headers (busca em headers)
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare exchange --name inbox_headers --type headers --durable true;


# Listar/Verificar exchanges no VHOST
rabbitmqctl list_exchanges -p vsite;

4.5 – Gestão de Queues e Bindings

Filas para receber mensagens da exchange fanout “inbox_fanout“:

Bash
# Queues (filas)
#-----------------------------------------------------------

# Criar fila queue_1001 no VHOST vsite:
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare queue --name queue_1001 --durable true;

# Criar filas de queue_1002:
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare queue --name queue_1002 --durable true;

# Criar filas de queue_1003:
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare queue --name queue_1003 --durable true;

# Listar/Verificar filas no VHOST
rabbitmqctl list_queues    -p vsite;


# Bindings (exchange -> binding routing -> queue)
#-----------------------------------------------------------

# exchange [inbox_fanout] => queue_1001
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_fanout \
        --destination-type queue \
        --destination queue_1001 \
        --routing-key "";

# exchange [inbox_fanout] => queue_1002
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_fanout \
        --destination-type queue \
        --destination queue_1002 \
        --routing-key "";

# exchange [inbox_fanout] => queue_1003
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_fanout \
        --destination-type queue \
        --destination queue_1003 \
        --routing-key "";

# Listar
rabbitmqctl list_exchanges -p vsite;
rabbitmqctl list_queues    -p vsite;
rabbitmqctl list_bindings  -p vsite;

Filas para receber mensagens da exchange direct “inbox_direct“:

Bash
# Queues (filas)
#-----------------------------------------------------------

# Criar fila log_error no VHOST vsite:
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare queue --name log_error --durable true;

# Criar filas de log_all:
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare queue --name log_all --durable true;

# Listar/Verificar filas no VHOST
rabbitmqctl list_queues    -p vsite;


# Bindings (exchange -> binding (check routing-key) -> queue)
#-----------------------------------------------------------

# exchange [inbox_direct] => (error) => log_error
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_direct \
        --destination-type queue \
        --destination log_error \
        --routing-key "error";

# exchange [inbox_fanout] => (error) => log_all
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_direct \
        --destination-type queue \
        --destination log_all \
        --routing-key "error";

# exchange [inbox_fanout] => (warn) => log_all
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_direct \
        --destination-type queue \
        --destination log_all \
        --routing-key "warning";

# exchange [inbox_fanout] => (info) => log_all
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_direct \
        --destination-type queue \
        --destination log_all \
        --routing-key "info";

# Listar
rabbitmqctl list_exchanges -p vsite;
rabbitmqctl list_queues    -p vsite;
rabbitmqctl list_bindings  -p vsite;

Filas para receber mensagens da exchange topic “inbox_topic“:

Bash
# Queues (filas)
#-----------------------------------------------------------

# Criar fila q.notifications no VHOST vsite:
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare queue --name q.notifications --durable true;

# Criar filas de q.orders:
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare queue --name q.orders --durable true;

# Criar filas de q.audit:
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare queue --name q.audit --durable true;

# Listar/Verificar filas no VHOST
rabbitmqctl list_queues    -p vsite;


# Bindings (exchange -> binding (pattern routing-key) -> queue)
#-----------------------------------------------------------

# exchange [inbox_topic] => (pattern) => q.notifications
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_topic \
        --destination-type queue \
        --destination q.notifications \
        --routing-key "com.vsite.notification.#";

# exchange [inbox_topic] => (pattern) => q.orders
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_topic \
        --destination-type queue \
        --destination q.orders \
        --routing-key "com.vsite.order.#";

# exchange [inbox_topic] => (pattern) => q.audit
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_topic \
        --destination-type queue \
        --destination q.audit \
        --routing-key "com.vsite.#";


# Listar
rabbitmqctl list_exchanges -p vsite;
rabbitmqctl list_queues    -p vsite;
rabbitmqctl list_bindings  -p vsite;

Filas para receber mensagens da exchange header “inbox_headers“:

Bash
# Queues (filas)
#-----------------------------------------------------------

# Criar fila q_images no VHOST vsite:
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare queue --name q_images --durable true;

# Criar filas de q_docs:
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare queue --name q_docs --durable true;

# Criar filas de q_compressed:
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare queue --name q_compressed --durable true;

# Criar filas de q_urgent:
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare queue --name q_urgent --durable true;


# Listar/Verificar filas no VHOST
rabbitmqctl list_queues    -p vsite;


# Bindings (exchange -> binding (header check) -> queue)
#-----------------------------------------------------------

# exchange [inbox_headers] => (header check) => q_images
# - Recebe somente se file_ext=jpg E origin=web (x-match: all)
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_headers \
        --destination-type queue \
        --destination q_images \
        --routing-key "" \
        --arguments '{"x-match":"all","file_ext":"jpg","origin":"web"}';

# exchange [inbox_headers] => (header check) => q_docs
# - Recebe se file_ext=pdf OU origin=scanner (x-match: any)
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_headers \
        --destination-type queue \
        --destination q_docs \
        --routing-key "" \
        --arguments '{"x-match":"any","file_ext":"pdf","origin":"scanner"}';

# exchange [inbox_headers] => (header check) => q_compressed
# - Recebe somente se file_ext=zip E compressed=true (x-match: all)
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_headers \
        --destination-type queue \
        --destination q_compressed \
        --routing-key "" \
        --arguments '{"x-match":"all","file_ext":"zip","compressed":"true"}';

# exchange [inbox_headers] => (header check) => q_urgent
# - Recebe se priority=urgent OU file_ext=exe (x-match: any)
rabbitmqadmin -u vsite_admin -p tulipa -V vsite \
    declare binding \
        --source inbox_headers \
        --destination-type queue \
        --destination q_urgent \
        --routing-key "" \
        --arguments '{"x-match":"any","priority":"urgent","file_ext":"exe"}';


# Listar
rabbitmqctl list_exchanges -p vsite;
rabbitmqctl list_queues    -p vsite;
rabbitmqctl list_bindings  -p vsite;

4.6 – Gestão de conexões

A gestão de conexões permite monitorar e controlar os clientes que estão conectados para PUBLISH e SUBSCRIPT.

Bash
# Listar consumidores:
rabbitmqctl list_consumers -p vsite;

# Conferir canais ativos:
rabbitmqctl list_channels  -p vsite;
    # Listing channels ...
    # pid   user    consumer_count messages_unacknowledged
    # <rabbit@rabbitmq.175435.64342.0> operador 1    0

# Desconectar canal:
    rabbitmqctl close_connection \
        "<rabbit@rabbitmq.175435.64342.0>"  "abuser"
        # Closing connection <rabbit@rabbitmq.175435.64342.0>, reason: abuser

# Listar filas com mais detalhes (default):
rabbitmqctl list_queues name messages consumers;

# Listar filas com mais detalhes no VHOST n8ntests:
rabbitmqctl list_queues -p vsite name messages consumers;

# Purgar uma fila (remover todas as mensagens):
rabbitmqctl purge_queue -p vsite queue_1001;
rabbitmqctl purge_queue -p vsite queue_1002;

5 – API do RabbitMQ

Já se você quiser controlar o sistema via API HTTP REST você pode usar as endpoints na URL publicada (https://rabbitmq.seudominio.com.br) ou diretamente na porta HTTP do MQ (http:// + endereco + :15672).

API Endpoint de teste básico de funcionamento do acesso à API: /api/whoami

Bash
# Variaveis
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER="admin";
    PASS="Sua_SenhaForte@";

# Acessando endpoint de teste de login:
    curl -u "$USER:$PASS" -X GET "$URL/api/whoami";

    # Retorno correto:
    # {"name":"operador","tags":["administrator"],"is_internal_user":true}
    
    # Retorno para falha de autenticacao:
    # {"error":"not_authorized","reason":"Not_Authorized"}

Endpoints informativas (método GET), troque o nome em negrito pelo nome do objeto desejado:

  • /api/overview
  • /api/nodes
  • /api/cluster-name
  • /api/healthchecks/node
  • /api/permissions
  • /api/users/username_here/permissions
  • /api/vhosts
  • /api/vhosts/vhostname_here/permissions
  • /api/exchanges
  • /api/exchanges/exchange_here
  • /api/queues
  • /api/queues/queue_here
  • /api/queues/vhostname_here/queue_here
  • /api/bindings
  • /api/bindings/vhostname_here
  • /api/exchanges/vhostname_here/broadcast_exchange/bindings/source
  • /api/queues/vhostname_here/queue_here/bindings
  • /api/connections
  • /api/connections/connection_name

Os objetos podem ser manipulados alterando o método HTTP (PUT para criar/atualizar, DELETE para remover).

5.1 – Manipulação de usuários

Exemplos para manipulação de usuários pela API:

Bash
# Variaveis
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER="admin";
    PASS="Sua_SenhaForte@";

# Listar usuários:
    curl -v -u "$USER:$PASS" -X GET "$URL/api/users";
    curl -s -u "$USER:$PASS" -X GET "$URL/api/users" | jq;

# Informações de um usuário (admin):
    curl -v -u "$USER:$PASS" -X GET \
        \
        "$URL/api/users/admin";

# Criar novo usuário xpto1 com senha senha123:
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        \
        -d '{"password":"senha123","tags":""}' \
        \
        "$URL/api/users/xpto1";

# Alterar senha do usuário xpto1 com senha 123mudar e add tag "administrator":
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        \
        -d '{"password":"123mudar","tags":"administrator"}' \
        \
        "$URL/api/users/xpto1";

# Deletar usuário
    curl -v -u "$USER:$PASS" -X DELETE \
        \
        "$URL/api/users/xpto1";

5.2 – Manipulação de VHOST

Exemplos para manipulação de virtual host pela API. A vhost “vsite” e o usuário “vsite_admin” serão utilizados nos próximos exemplos.

Bash
# Variaveis
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER="admin";
    PASS="Sua_SenhaForte@";

# Listar vhosts
    curl -v -u "$USER:$PASS" -X GET "$URL/api/vhosts";
    curl -s -u "$USER:$PASS" -X GET "$URL/api/vhosts" | jq;
    curl -s -u "$USER:$PASS" -X GET "$URL/api/vhosts" | jq '.[].name';

# Criar vhost "vsite"
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        "$URL/api/vhosts/vsite";

# Adicionar usuario "vsite_admin"
    # Tags:
    # - management: permite criar estrutura mas nao pode postar
    # - administrator: permite tudo
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d "{\"password\":\"tulipa\",\"tags\":\"administrator\"}" \
        "$URL/api/users/vsite_admin";

# Listar permissoes do usuario
    curl -v -u "$USER:$PASS" -X GET "$URL/api/users/vsite_admin/permissions";
    curl -s -u "$USER:$PASS" -X GET "$URL/api/users/vsite_admin/permissions" | jq;

# Definir permissoes no vhost
    #-curl -v -u "$USER:$PASS" \
    #-    -X PUT \
    #-    -H "content-type:application/json" \
    #-    -d '{"configure":".*","write":".*","read":".*"}' \
    #-    "$URL/api/permissions/vsite/vsite_admin";

# Remover todas as tags do usuario
    #-curl -v -u "$USER:$PASS" \
    #-    -X PUT \
    #-    -H "content-type:application/json" \
    #-    -d '{"tags":""}' \
    #-    "$URL/api/users/vsite_admin";

# Definir tag management no usuario
    #-curl -v -u "$USER:$PASS" \
    #-    -X PUT \
    #-    -H "content-type:application/json" \
    #-    -d '{"tags":"administrator"}' \
    #-    "$URL/api/users/vsite_admin";

# Conferir detalhes do usuario "vsite_admin"
    curl -s -u "$USER:$PASS" "$URL/api/users/vsite_admin"             | jq;
    curl -s -u "$USER:$PASS" "$URL/api/users/vsite_admin/permissions" | jq;

5.3 – Manipulação de exchanges

Exemplos para manipulação de exchanges pela API:

Bash
# Variaveis
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER="vsite_admin";
    PASS="tulipa";

# Listar exchanges
    curl -v -u "$USER:$PASS" -X GET "$URL/api/exchanges";
    curl -s -u "$USER:$PASS" -X GET "$URL/api/exchanges" | jq;
    curl -s -u "$USER:$PASS" -X GET "$URL/api/exchanges" | jq '.[].name';

# Criar exchanges
# Criar exchange tipo fanout (broadcast)
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"type":"fanout","durable":true}' \
        \
        "$URL/api/exchanges/vsite/inbox_fanout";

# Criar exchange tipo direct (routing-key exata)
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"type":"direct","durable":true}' \
        "$URL/api/exchanges/vsite/inbox_direct";

# Criar exchange tipo topic (routing-key pattern * #)
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"type":"topic","durable":true}' \
        "$URL/api/exchanges/vsite/inbox_topic";

# Criar exchange tipo headers (busca em headers)
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"type":"headers","durable":true}' \
        "$URL/api/exchanges/vsite/inbox_headers";

# Deletar exchanges:
    #curl -v -u "$USER:$PASS" -X DELETE "$URL/api/exchanges/vsite/inbox_fanout";
    #curl -v -u "$USER:$PASS" -X DELETE "$URL/api/exchanges/vsite/inbox_direct";
    #curl -v -u "$USER:$PASS" -X DELETE "$URL/api/exchanges/vsite/inbox_topic";
    #curl -v -u "$USER:$PASS" -X DELETE "$URL/api/exchanges/vsite/inbox_headers";

5.3 – Manipulação de filas (queues)

Listar queues:

Bash
# Variaveis
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER="vsite_admin";
    PASS="tulipa";

# Listar filas (todas)
    curl -v -u "$USER:$PASS" -X GET "$URL/api/queues";
    curl -s -u "$USER:$PASS" -X GET "$URL/api/queues" | jq;
    curl -s -u "$USER:$PASS" -X GET "$URL/api/queues" | jq '.[].name';

Filas para receber mensagens da exchange fanout “inbox_fanout“:

Bash
# Variaveis
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER="vsite_admin";
    PASS="tulipa";

# Queues (filas) no VHOST "vsite"
#-----------------------------------------------------------

# Criar fila queue_1001
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"durable":true}' \
        "$URL/api/queues/vsite/queue_1001";

# Criar fila queue_1002
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"durable":true}' \
        "$URL/api/queues/vsite/queue_1002";

# Criar fila queue_1003
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"durable":true}' \
        "$URL/api/queues/vsite/queue_1003";

# Listar filas
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite"    | jq;
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite"    | jq '.[].name';


# Bindings
#-----------------------------------------------------------

# exchange [inbox_fanout] => queue_1001
    JSON='{
        "routing_key":"",
        "destination_type":"queue",
        "destination":"queue_1001",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_fanout/q/queue_1001";

# exchange [inbox_fanout] => queue_1002
    JSON='{
        "routing_key":"",
        "destination_type":"queue",
        "destination":"queue_1002",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_fanout/q/queue_1002";

# exchange [inbox_fanout] => queue_1003
    JSON='{
        "routing_key":"",
        "destination_type":"queue",
        "destination":"queue_1003",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_fanout/q/queue_1003";

# Listar tudo
    curl -s -u "$USER:$PASS" "$URL/api/exchanges/vsite" | jq;
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite"    | jq;
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite"    | jq '.[].name';
    curl -s -u "$USER:$PASS" "$URL/api/bindings/vsite"  | jq;

Filas para receber mensagens da exchange direct “inbox_direct“:

Bash
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER="vsite_admin";
    PASS="tulipa";

# Queues (filas) no VHOST "vsite"
#-----------------------------------------------------------

# Criar fila log_error
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"durable":true}' \
        "$URL/api/queues/vsite/log_error";

# Criar fila log_all
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"durable":true}' \
        "$URL/api/queues/vsite/log_all";

# Criar fila log_recent (mensagens com tempo de vida na fila)
    JSON='
    {
        "durable":true,
        "arguments": {"x-message-ttl":60000,"x-max-length":1000}
    }';
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/queues/vsite/log_recent";


# Listar/Verificar filas no VHOST
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite" | jq;
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite" | jq '.[].name';


# Bindings (exchange -> binding (check routing-key) -> queue)
#-----------------------------------------------------------

# exchange [inbox_direct] => (error) => log_error
    JSON='{
        "routing_key":"error",
        "destination_type":"queue",
        "destination":"log_error",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_direct/q/log_error";

# exchange [inbox_direct] => (error) => log_all
    JSON='{
        "routing_key":"error",
        "destination_type":"queue",
        "destination":"log_all",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_direct/q/log_all";

# exchange [inbox_direct] => (warning) => log_all
    JSON='{
        "routing_key":"warning",
        "destination_type":"queue",
        "destination":"log_all",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_direct/q/log_all";

# exchange [inbox_direct] => (info) => log_all
    JSON='{
        "routing_key":"info",
        "destination_type":"queue",
        "destination":"log_all",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_direct/q/log_all";


# criar bindings para copiar todos os tipos para a fila temporaria log_recent
    # - error
    JSON='{
        "routing_key":"error",
        "destination_type":"queue",
        "destination":"log_recent",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_direct/q/log_recent";

    # - warning
    JSON='{
        "routing_key":"warning",
        "destination_type":"queue",
        "destination":"log_recent",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_direct/q/log_recent";

    # - info
    JSON='{
        "routing_key":"info",
        "destination_type":"queue",
        "destination":"log_recent",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_direct/q/log_recent";


# Listar tudo
    curl -s -u "$USER:$PASS" "$URL/api/exchanges/vsite" | jq;
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite"    | jq;
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite"    | jq '.[].name';
    curl -s -u "$USER:$PASS" "$URL/api/bindings/vsite"  | jq;

Filas para receber mensagens da exchange topic “inbox_topic“:

Bash
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER="vsite_admin";
    PASS="tulipa";

# Queues (filas) no VHOST "vsite"
#-----------------------------------------------------------

# Criar fila q.notifications
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"durable":true}' \
        "$URL/api/queues/vsite/q.notifications";

# Criar fila q.orders
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"durable":true}' \
        "$URL/api/queues/vsite/q.orders";

# Criar fila q.audit
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"durable":true}' \
        "$URL/api/queues/vsite/q.audit";

# Listar/Verificar filas no VHOST
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite"    | jq;
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite"    | jq '.[].name';


# Bindings (exchange -> binding (pattern routing-key) -> queue)
#-----------------------------------------------------------

# exchange [inbox_topic] => (com.vsite.notification.#) => q.notifications
    JSON='{
        "routing_key":"com.vsite.notification.#",
        "destination_type":"queue",
        "destination":"q.notifications",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_topic/q/q.notifications";

# exchange [inbox_topic] => (com.vsite.order.#) => q.orders
    JSON='{
        "routing_key":"com.vsite.order.#",
        "destination_type":"queue",
        "destination":"q.orders",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_topic/q/q.orders";

# exchange [inbox_topic] => (com.vsite.#) => q.audit
    JSON='{
        "routing_key":"com.vsite.#",
        "destination_type":"queue",
        "destination":"q.audit",
        "arguments":{}
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_topic/q/q.audit";

# Listar tudo
    curl -s -u "$USER:$PASS" "$URL/api/exchanges/vsite" | jq;
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite"    | jq;
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite"    | jq '.[].name';
    curl -s -u "$USER:$PASS" "$URL/api/bindings/vsite"  | jq;

Filas para receber mensagens da exchange header “inbox_headers“:

Bash
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER="vsite_admin";
    PASS="tulipa";

# Queues (filas) no VHOST "vsite"
#-----------------------------------------------------------

# Criar fila q_images
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"durable":true}' \
        "$URL/api/queues/vsite/q_images";

# Criar fila q_docs
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"durable":true}' \
        "$URL/api/queues/vsite/q_docs";

# Criar fila q_compressed
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"durable":true}' \
        "$URL/api/queues/vsite/q_compressed";

# Criar fila q_urgent
    curl -v -u "$USER:$PASS" \
        -X PUT \
        -H "content-type:application/json" \
        -d '{"durable":true}' \
        "$URL/api/queues/vsite/q_urgent";

# Listar/Verificar filas no VHOST
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite" | jq;
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite" | jq '.[].name';


# Bindings (exchange -> binding (header check) -> queue)
#-----------------------------------------------------------

# exchange [inbox_headers] => (header check) => q_images
# - Recebe somente se file_ext=jpg E origin=web (x-match: all)
    JSON='{
        "routing_key":"",
        "destination_type":"queue",
        "destination":"q_images",
        "arguments":{
            "x-match":"all",
            "file_ext":"jpg",
            "origin":"web"
        }
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_headers/q/q_images";

# exchange [inbox_headers] => (header check) => q_docs
# - Recebe se file_ext=pdf OU origin=scanner (x-match: any)
    JSON='{
        "routing_key":"",
        "destination_type":"queue",
        "destination":"q_docs",
        "arguments":{
            "x-match":"any",
            "file_ext":"pdf",
            "origin":"scanner"
        }
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_headers/q/q_docs";

# exchange [inbox_headers] => (header check) => q_compressed
# - Recebe somente se file_ext=zip E compressed=true (x-match: all)
    JSON='{
        "routing_key":"",
        "destination_type":"queue",
        "destination":"q_compressed",
        "arguments":{
            "x-match":"all",
            "file_ext":"zip",
            "compressed":"true"
        }
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_headers/q/q_compressed";

# exchange [inbox_headers] => (header check) => q_urgent
# - Recebe se priority=urgent OU file_ext=exe (x-match: any)
    JSON='{
        "routing_key":"",
        "destination_type":"queue",
        "destination":"q_urgent",
        "arguments":{
            "x-match":"any",
            "priority":"urgent",
            "file_ext":"exe"
        }
    }';
    curl -v -u "$USER:$PASS" \
        -X POST \
        -H "content-type:application/json" \
        -d "$JSON" \
        "$URL/api/bindings/vsite/e/inbox_headers/q/q_urgent";

# Listar tudo
    curl -s -u "$USER:$PASS" "$URL/api/exchanges/vsite" | jq;
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite"    | jq;
    curl -s -u "$USER:$PASS" "$URL/api/queues/vsite"    | jq '.[].name';
    curl -s -u "$USER:$PASS" "$URL/api/bindings/vsite"  | jq;

6 – Utilizando as filas

Com nossas exchanges, filas e roteamento prontos, vamos explorar exemplos de como publicar e receber mensagens.

6.1 – Publicando na exchange

Exemplo de envio de mensagens para a exchange (vsite => inbox_fanout):

Bash
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER_API="vsite_admin";
    PASS_API="tulipa";

# Criar JSON das mensagens
    # - Mensagem 1
    JSON_1='{
        "properties":{},
        "routing_key":"nao-importa-1",
        "payload_encoding": "string",
        "payload":"A ligeira rapousa morrom ataca o cao preguicoso"
    }';
    # - Mensagem 2
    JSON_2='{
        "properties":{},
        "routing_key":"nao-importa-2",
        "payload_encoding": "string",
        "payload":"Lorem ipsum dolor sit amet, consectetur adipiscing elit"
    }';
    # - Mensagem 3
    JSON_3='{
        "properties":{},
        "routing_key":"tanto-faz",
        "payload_encoding": "string",
        "payload":"Duis aute irure dolor in reprehenderit"
    }';

    # - Mensagem 4 detalhada
    JSON_FULL='
    {
        "routing_key": "qualquer.chave",
        "payload": "{\"event\": \"pedido_criado\", \"id\": 42, \"valor\": 199.90}",
        "payload_encoding": "string",
        "properties": {
            "content_type": "application/json",
            "content_encoding": "utf-8",
            "delivery_mode": 2,
            "priority": 5,
            "correlation_id": "req-abc-123",
            "reply_to": "fila.de.resposta",
            "expiration": "60000",
            "message_id": "msg-uuid-9999",
            "timestamp": 1700000000,
            "type": "pedido.criado",
            "user_id": "vsite_admin",
            "app_id": "minha-aplicacao",
            "headers": {
                "x-origem": "checkout",
                "x-versao": "2"
            }
        }
    }';

# Enviar mensagens para a exchange "inbox_fanout" no vhost "vsite"
    curl -v -u "$USER_API:$PASS_API" -H "Content-Type: application/json" \
        -X POST -d "$JSON_1" \
        "$URL/api/exchanges/vsite/inbox_fanout/publish";
        # -> {"routed":true}

    curl -v -u "$USER_API:$PASS_API" -H "Content-Type: application/json" \
        -X POST -d "$JSON_2" \
        "$URL/api/exchanges/vsite/inbox_fanout/publish";
        # -> {"routed":true}

    curl -v -u "$USER_API:$PASS_API" -H "Content-Type: application/json" \
        -X POST -d "$JSON_3" \
        "$URL/api/exchanges/vsite/inbox_fanout/publish";
        # -> {"routed":true}

# Enviar mensagens completa para a exchange "inbox_fanout" no vhost "vsite"
    curl -v -u "$USER_API:$PASS_API" -H "Content-Type: application/json" \
        -X POST -d "$JSON_FULL" \
        "$URL/api/exchanges/vsite/inbox_fanout/publish";
        # -> {"routed":true}

Exemplo de envio de mensagens para a exchange (vsite => inbox_direct):

Bash
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER_API="vsite_admin";
    PASS_API="tulipa";

# Criar JSON com diferentes mensagens
    # - Mensagem de log informativo
    JSON_INFO='{
        "properties":{},
        "routing_key":"info",
        "payload_encoding": "string",
        "payload":"O rato roeu a roupa do rei de roma"
    }';
    # - Mensagem de log alerta
    JSON_WARNING='{
        "properties":{},
        "routing_key":"warning",
        "payload_encoding": "string",
        "payload":"Temperatura da caldeira 1 no limite, 99c"
    }';
    # - Mensagem de log falha/erro
    JSON_ERROR='{
        "properties":{},
        "routing_key":"error",
        "payload_encoding": "string",
        "payload":"Temperatura da caldeira 2 critica, 120c"
    }';

# Enviar mensagens para a exchange "inbox_direct" no vhost "vsite"
    curl -v -u "$USER_API:$PASS_API" \
        -H "Content-Type: application/json" \
        -X POST \
        -d "$JSON_INFO" \
        "$URL/api/exchanges/vsite/inbox_direct/publish";

    curl -v -u "$USER_API:$PASS_API" \
        -H "Content-Type: application/json" \
        -X POST \
        -d "$JSON_WARNING" \
        "$URL/api/exchanges/vsite/inbox_direct/publish";

    curl -v -u "$USER_API:$PASS_API" \
        -H "Content-Type: application/json" \
        -X POST \
        -d "$JSON_ERROR" \
        "$URL/api/exchanges/vsite/inbox_direct/publish";

Exemplo de envio de mensagens para a exchange (vsite => inbox_topic):

Bash
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER_API="vsite_admin";
    PASS_API="tulipa";

# Mensagem para q.notifications (match: com.vsite.notification.#)
    JSON_NOTIFICATION='{
        "properties": {
            "delivery_mode": 2
        },
        "routing_key": "com.vsite.notification.email",
        "payload_encoding": "string",
        "payload": "Novo usuario cadastrado, enviar email de boas-vindas"
    }';

# Mensagem para q.orders (match: com.vsite.order.#)
    JSON_ORDER='{
        "properties": {
            "delivery_mode": 2
        },
        "routing_key": "com.vsite.order.created",
        "payload_encoding": "string",
        "payload": "Pedido #4521 criado, aguardando pagamento"
    }';

# Mensagem que cai apenas em q.audit
# (match: com.vsite.# mas nao notification nem order)
    JSON_AUDIT_ONLY='{
        "properties": {
            "delivery_mode": 2
        },
        "routing_key": "com.vsite.auth.login",
        "payload_encoding": "string",
        "payload": "Usuario admin autenticado em 2024-01-15 10:32:00"
    }';

# Enviar para inbox_topic
    curl -s -u "$USER_API:$PASS_API" \
        -H "Content-Type: application/json" \
        -X POST \
        -d "$JSON_NOTIFICATION" \
        "$URL/api/exchanges/vsite/inbox_topic/publish";

    curl -s -u "$USER_API:$PASS_API" \
        -H "Content-Type: application/json" \
        -X POST \
        -d "$JSON_ORDER" \
        "$URL/api/exchanges/vsite/inbox_topic/publish";

    curl -s -u "$USER_API:$PASS_API" \
        -H "Content-Type: application/json" \
        -X POST \
        -d "$JSON_AUDIT_ONLY" \
        "$URL/api/exchanges/vsite/inbox_topic/publish";

Exemplo de envio de mensagens para a exchange (vsite => inbox_headers):

Bash
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER_API="vsite_admin";
    PASS_API="tulipa";


# q_images: file_ext=jpg E origin=web (x-match: all)
# --------------------------------------------------------------
    JSON='{
        "properties": {
            "delivery_mode": 2,
            "headers": {
                "file_ext": "jpg",
                "origin": "web"
            }
        },
        "routing_key": "",
        "payload_encoding": "string",
        "payload": "Arquivo imagem.jpg enviado pelo portal web"
    }';

    curl -s -u "$USER_API:$PASS_API" \
        -H "Content-Type: application/json" \
        -X POST \
        -d "$JSON" \
        "$URL/api/exchanges/vsite/inbox_headers/publish";


# q_docs via file_ext=pdf: cai em q_docs (any: file_ext=pdf)
# --------------------------------------------------------------
    JSON='{
        "properties": {
            "delivery_mode": 2,
            "headers": {
                "file_ext": "pdf",
                "origin": "web"
            }
        },
        "routing_key": "",
        "payload_encoding": "string",
        "payload": "Documento contrato.pdf enviado pelo portal web"
    }';

    curl -s -u "$USER_API:$PASS_API" \
        -H "Content-Type: application/json" \
        -X POST \
        -d "$JSON" \
        "$URL/api/exchanges/vsite/inbox_headers/publish";


# q_docs via origin=scanner: cai em q_docs (any: origin=scanner)
# --------------------------------------------------------------
    JSON='{
        "properties": {
            "delivery_mode": 2,
            "headers": {
                "file_ext": "png",
                "origin": "scanner"
            }
        },
        "routing_key": "",
        "payload_encoding": "string",
        "payload": "Documento digitalizado pelo scanner"
    }';

    curl -s -u "$USER_API:$PASS_API" \
        -H "Content-Type: application/json" \
        -X POST \
        -d "$JSON" \
        "$URL/api/exchanges/vsite/inbox_headers/publish";


# q_compressed: file_ext=zip E compressed=true (x-match: all)
# --------------------------------------------------------------
    JSON='{
        "properties": {
            "delivery_mode": 2,
            "headers": {
                "file_ext": "zip",
                "compressed": "true"
            }
        },
        "routing_key": "",
        "payload_encoding": "string",
        "payload": "Pacote backup.zip compactado para processamento"
    }';
    
    curl -s -u "$USER_API:$PASS_API" \
        -H "Content-Type: application/json" \
        -X POST \
        -d "$JSON" \
        "$URL/api/exchanges/vsite/inbox_headers/publish";


# q_urgent via priority=urgent
# --------------------------------------------------------------
    JSON='{
        "properties": {
            "delivery_mode": 2,
            "headers": {
                "file_ext": "txt",
                "priority": "urgent"
            }
        },
        "routing_key": "",
        "payload_encoding": "string",
        "payload": "Alerta critico de sistema, processar imediatamente"
    }';

    curl -s -u "$USER_API:$PASS_API" \
        -H "Content-Type: application/json" \
        -X POST \
        -d "$JSON" \
        "$URL/api/exchanges/vsite/inbox_headers/publish";


# q_urgent via file_ext=exe
# --------------------------------------------------------------
    JSON='{
        "properties": {
            "delivery_mode": 2,
            "headers": {
                "file_ext": "exe",
                "origin": "web"
            }
        },
        "routing_key": "",
        "payload_encoding": "string",
        "payload": "Executavel recebido, encaminhar para analise de seguranca"
    }';

    curl -s -u "$USER_API:$PASS_API" \
        -H "Content-Type: application/json" \
        -X POST \
        -d "$JSON" \
        "$URL/api/exchanges/vsite/inbox_headers/publish";

6.2 – Coletando mensagem da fila

Vamos coletar mensagens das filas.

Observação: consumir mensagens pela API HTTP não dá suporte a ACK. O simples fato de pegar a mensagem resulta na remoção da mesma na fila.

Bash
# Variaveis
    # - Nome de DNS para acesso pelo navegador
    URL="https://rabbitmq.seudominio.com.br";

    # - Login para usar a API:
    USER_API="vsite_admin";
    PASS_API="tulipa";

# Consumir uma única mensagem (a mais antiga) de uma fila:
    curl -v -u "$USER_API:$PASS_API" \
        -X POST \
        -H "content-type:application/json" \
        -d '{"count":1,"ackmode":"ack_requeue_false","encoding":"auto"}' \
        "$URL/api/queues/vsite/queue_1001/get" | jq;

        # Retorno: lista JSON, cada objeto é uma mensagem coletada:
        # [
        #   {
        #     "payload_bytes": 55,
        #     "redelivered": false,
        #     "exchange": "inbox_fanout",
        #     "routing_key": "nao-importa-2",
        #     "message_count": 9,
        #     "properties": [],
        #     "payload": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
        #     "payload_encoding": "string"
        #   }
        # ]

# Consumir múltiplas mensagens (limite de 5 por coleta):
    curl -v -u "$USER_API:$PASS_API" \
        -X POST -H "content-type:application/json" \
        -d '{"count":5,"ackmode":"ack_requeue_false","encoding":"auto"}' \
        "$URL/api/queues/vsite/queue_1001/get" | jq;

      # Retorno: lista JSON, cada objeto é uma mensagem coletada:
      # [
      #     { "payload_bytes": 19, … },
      #     { "payload_bytes": 32, … },
      #     { "payload_bytes": 21, … },
      #     { "payload_bytes": 18, … },
      #     { "payload_bytes": 23, … }
      # ]

Não há assunto tão velho que não possa ser dito algo de novo sobre ele.
Fiódor Dostoiévski

Terminamos por hoje!

Patrick Brandão, patrickbrandao@gmail.com