Filas

Filas com RabbitMQ

O motor RabbitMQ® de Filas oferece mensageria completa para microsserviços: exchanges, routing keys, confirmações e dead-letter. A versão é a 4.4 e o protocolo é AMQP 0-9-1. Para tarefas simples em segundo plano, o motor Valkey pode ser suficiente; veja a comparação em Filas: escolha o motor.

Planos e alta disponibilidade

O RabbitMQ usa os mesmos planos pagos e os mesmos preços das demais Filas: queue-starter, queue-basic, queue-premium e queue-enterprise. Não há plano gratuito para RabbitMQ; o queue-free é só do Valkey. Consulte capacidade e preço no guia de planos.

PlanoNósTipo de fila padrãoMétricas
queue-starter1clássicanão
queue-basic3, com alta disponibilidadequorumnão
queue-premium3, com alta disponibilidadequorumsim
queue-enterprise3, com alta disponibilidadequorumsim

As filas quorum replicam cada mensagem entre os nós e continuam disponíveis se um nó falhar. Nos planos com 1 nó não há réplica: se o nó ficar indisponível, a fila espera ele voltar. Entre os planos Basic, Premium e Enterprise, troque o plano no card Plano da edição do projeto (permissão Permitir mudança de plano): os 3 nós reiniciam um de cada vez, as conexões abertas caem e a aplicação precisa reconectar, e as filas e mensagens guardadas são mantidas. O Enterprise exige pelo menos 20 GB de armazenamento; amplie o armazenamento antes de trocar para ele. O Starter tem 1 nó e não troca de plano; para sair dele, crie uma fila nova no plano desejado. Para ganhar espaço, aumente o armazenamento. Veja Armazenamento e a API de armazenamento.

Conexão

A conexão usa TLS e tem este formato:

amqps://app:<senha>@rabbitmq-<id>.managed.zenifra.com:<porta>/
  • Usuário: app. Virtual host: /.
  • A senha é exibida apenas na criação e depois de uma rotação de credencial. Depois disso, o Console mostra a URL com a senha mascarada.
  • Fora da Zenifra, somente conexões TLS (amqps) são aceitas.
  • Guarde a URL como variável de ambiente protegida (por exemplo, RABBITMQ_URL) no projeto da aplicação.

Por padrão, o host e a porta são públicos. Você pode desligar o acesso público; nesse caso, o serviço só é alcançado pelas conexões privadas entre aplicações. A resposta de GET /v1/managed-services/:id/connection informa o estado em exposure.

Conexão privada

Aplicações da sua organização ligadas ao RabbitMQ por uma conexão privada usam o endereço interno <projeto>.<id-da-organização>.zenifra.local, na porta 5672 com amqp://; o tráfego fica dentro da rede privada. O passo a passo está em Conexão privada com o RabbitMQ.

Node.js e TypeScript

npm install amqplib
import amqp from 'amqplib'

const connection = await amqp.connect(process.env.RABBITMQ_URL!)
const channel = await connection.createConfirmChannel()

// Exchange de dead-letter e a fila que guarda as mensagens rejeitadas
await channel.assertExchange('orders.dlx', 'direct', { durable: true })
await channel.assertQueue('orders.dead', { durable: true })
await channel.bindQueue('orders.dead', 'orders.dlx', 'created')

// Exchange principal, fila de trabalho e binding por routing key
await channel.assertExchange('orders', 'topic', { durable: true })
await channel.assertQueue('orders.created', {
  durable: true,
  arguments: {
    'x-dead-letter-exchange': 'orders.dlx',
    'x-dead-letter-routing-key': 'created',
  },
})
await channel.bindQueue('orders.created', 'orders', 'orders.created')

// Publicação persistente, com confirmação do servidor
channel.publish('orders', 'orders.created', Buffer.from(JSON.stringify({ id: 42 })), {
  persistent: true,
  contentType: 'application/json',
})
await channel.waitForConfirms()

// Consumo com confirmação manual
await channel.prefetch(10)
await channel.consume('orders.created', async (message) => {
  if (!message) return
  try {
    console.log('process message', JSON.parse(message.content.toString()))
    channel.ack(message)
  } catch {
    channel.nack(message, false, false) // sem reenfileirar: vai para a dead-letter
  }
})

O amqplib valida o certificado do servidor quando a URL usa amqps://. O processamento deve ser idempotente: uma mensagem pode ser entregue mais de uma vez depois de uma falha ou de uma reconexão.

Python

python -m pip install pika
import json
import os
import ssl
from urllib.parse import urlparse

import pika

url = os.environ["RABBITMQ_URL"]
params = pika.URLParameters(url)
params.ssl_options = pika.SSLOptions(ssl.create_default_context(), urlparse(url).hostname)

connection = pika.BlockingConnection(params)
channel = connection.channel()
channel.confirm_delivery()

# Dead-letter
channel.exchange_declare("orders.dlx", exchange_type="direct", durable=True)
channel.queue_declare("orders.dead", durable=True)
channel.queue_bind("orders.dead", "orders.dlx", routing_key="created")

# Exchange principal, fila de trabalho e binding por routing key
channel.exchange_declare("orders", exchange_type="topic", durable=True)
channel.queue_declare(
    "orders.created",
    durable=True,
    arguments={"x-dead-letter-exchange": "orders.dlx", "x-dead-letter-routing-key": "created"},
)
channel.queue_bind("orders.created", "orders", routing_key="orders.created")

# Publicação persistente (a confirmação do servidor é aguardada)
channel.basic_publish(
    "orders",
    "orders.created",
    json.dumps({"id": 42}),
    properties=pika.BasicProperties(delivery_mode=2, content_type="application/json"),
)

# Consumo com confirmação manual
def handle(ch, method, properties, body):
    try:
        print("process message", json.loads(body))
        ch.basic_ack(method.delivery_tag)
    except Exception:
        ch.basic_nack(method.delivery_tag, requeue=False)  # vai para a dead-letter

channel.basic_qos(prefetch_count=10)
channel.basic_consume("orders.created", on_message_callback=handle)
channel.start_consuming()

Exchanges, routing keys e dead-letter

  • Exchange: recebe a mensagem do produtor e a roteia para as filas ligadas a ela. Os tipos mais usados são direct (routing key exata), topic (padrões como orders.*) e fanout (todas as filas).
  • Routing key: etiqueta que o produtor coloca na mensagem e que o binding usa para decidir a fila de destino.
  • Confirmações: o consumidor confirma com ack depois de processar; com nack sem reenfileirar, a mensagem segue para a dead-letter. A confirmação de publicação (waitForConfirms, confirm_delivery) garante que o servidor recebeu a mensagem.
  • Dead-letter: declare a fila com x-dead-letter-exchange (e, se quiser, x-dead-letter-routing-key). As mensagens rejeitadas com nack sem reenfileirar ou expiradas vão para a exchange indicada.

Você configura tudo pelo próprio cliente AMQP, no código da aplicação: o usuário app pode criar, alterar e remover exchanges, filas e bindings no virtual host /. Os argumentos mais usados ao declarar uma fila são x-queue-type, x-message-ttl (validade das mensagens), x-max-length e x-max-length-bytes (abaixo do limite do plano), x-dead-letter-exchange e x-single-active-consumer. Não há painel de gerenciamento nem API HTTP do RabbitMQ, e as políticas do servidor são definidas pela Zenifra, como a do tamanho máximo da fila de cada plano.

Ao declarar uma fila sem x-queue-type, ela usa o tipo padrão do plano. Redeclarar uma fila já existente com argumentos diferentes causa erro; crie uma fila nova ou remova a antiga.

Mensagens com entrega agendada

Para entregar uma mensagem só a partir de um horário, publique com o header x-opt-delivery-time: o horário de entrega em milissegundos desde 1970 (Unix epoch), como número inteiro. A fila guarda a mensagem na hora e só a entrega aos consumidores quando o horário chega. Não precisa de plugin nem de exchange especial.

// Entrega daqui a 10 minutos
channel.publish('orders', 'orders.reminder', Buffer.from(JSON.stringify({ id: 42 })), {
  persistent: true,
  headers: { 'x-opt-delivery-time': Date.now() + 10 * 60 * 1000 },
})
import time

channel.basic_publish(
    exchange="orders",
    routing_key="orders.reminder",
    body=json.dumps({"id": 42}),
    properties=pika.BasicProperties(
        delivery_mode=2,
        headers={"x-opt-delivery-time": int(time.time() * 1000) + 10 * 60 * 1000},
    ),
)
  • Funciona em filas do tipo quorum, o padrão nos planos Basic, Premium e Enterprise. No Starter, o padrão é a fila clássica, que ignora o header e entrega na hora; declare a fila com x-queue-type: quorum para usar a entrega agendada.
  • As mensagens saem na ordem do horário de entrega, não na ordem de publicação, e contam para o tamanho máximo da fila enquanto esperam.
  • Nos nossos testes, nenhuma mensagem saiu antes do horário, e a entrega ocorreu de 5 a 70 ms depois dele. Mensagens agendadas antes de uma troca de plano foram entregues no horário certo depois da troca.
  • O plugin antigo rabbitmq_delayed_message_exchange (header x-delay) não está disponível; use x-opt-delivery-time.

Limites por plano

PlanoConexõesCanais por conexãoCanais no totalTamanho máximo da mensagemTamanho máximo da fila
queue-starter1001284004 MiB128 MiB
queue-basic3002561.20016 MiB256 MiB
queue-premium1.0005123.00016 MiB512 MiB
queue-enterprise5.0001.02412.00016 MiB2 GiB

Estes são os limites atuais e podem mudar. "Canais no total" soma os canais de todas as conexões; ao passar dele, o servidor recusa o novo canal. Quando uma fila atinge o tamanho máximo, novas publicações nela são rejeitadas. Quando a memória do serviço enche, as publicações ficam bloqueadas até que os consumidores esvaziem mensagens; mantenha consumidores ativos e acompanhe as métricas.

Desempenho medido

Medimos cada plano em novembro de 2026 com a carga que recomendamos para não perder mensagens: filas duráveis do tipo padrão do plano, mensagens persistentes de 1 KiB, confirmação de publicação e ack manual no consumidor. O cliente usou amqplib (Node.js), conectado pela URL pública com TLS a partir da mesma região, e todas as mensagens confirmadas foram entregues.

Vazão (mensagens publicadas e consumidas por segundo, do começo ao fim do teste):

Plano1 fila, 2 produtores e 2 consumidores4 filas, 1 produtor e 1 consumidor em cada
queue-startercerca de 3.100cerca de 3.100
queue-basiccerca de 6.700cerca de 8.800
queue-premiumcerca de 8.900cerca de 10.000
queue-enterprisecerca de 7.500cerca de 9.600

Latência (da publicação até a entrega ao consumidor):

Plano100 mensagens/s: mediana100 mensagens/s: p991.000 mensagens/s: mediana1.000 mensagens/s: p99
queue-starter1,5 ms4,2 ms3,7 ms27 ms
queue-basic7,2 ms13 ms12 ms23 ms
queue-premium7,9 ms39 ms12 ms42 ms
queue-enterprise8,2 ms17 ms12 ms32 ms

Como ler esses números:

  • No Starter, a fila clássica de 1 nó responde mais rápido, mas a CPU do plano chega ao limite perto de 3.000 mensagens por segundo. Com o servidor no limite, publicar ganha prioridade e o consumo atrasa; as mensagens ficam na fila e são entregues depois.
  • A partir do Basic, cada mensagem é gravada em disco nos 3 nós antes da confirmação. Isso soma alguns milissegundos à latência e põe uma única fila perto de 7.000 a 9.000 mensagens por segundo, qualquer que seja o plano. Distribuir a carga entre várias filas aumenta um pouco a vazão total: com 16 filas em paralelo, o Basic ficou em cerca de 8.400 e o Enterprise em cerca de 11.300 mensagens por segundo, com CPU de sobra nos dois.
  • Os planos maiores não deixam uma mensagem mais rápida: eles aceitam mais conexões e canais, guardam filas maiores e têm folga de CPU e memória para muitas filas, consumidores e picos.
  • Os resultados variam com o tamanho das mensagens, o número de filas e de conexões, o uso de confirmações e a distância entre a aplicação e o serviço. Para decidir, meça a sua própria carga em uma fila de teste por hora e remova-a ao terminar.

Troca de plano com tráfego

Trocamos o plano de Basic para Premium e de Premium para Enterprise com um produtor e um consumidor ligados, publicando 200 mensagens por segundo, e com 1.000 mensagens guardadas em outra fila, sem consumidor:

MedidaResultado
Duração da troca, com os 3 nós reiniciando um de cada vezcerca de 4 minutos
Mensagens confirmadas que se perderamnenhuma
Quedas de conexão do produtor e do consumidor2 de cada, com reconexão em cerca de 1 segundo
Maior pausa sem confirmação de publicaçãocerca de 1,4 segundo
Mensagens entregues duas vezescerca de 0,03%, todas reentregues pelo servidor com redelivered marcado, porque o ack do consumidor não chegou antes da queda
Mensagens guardadas lidas depois da troca, com a mesma credencial e na mesma fila1.000 de 1.000

Para atravessar a troca sem perder mensagens, a aplicação precisa reconectar sozinha, reenviar as publicações que não foram confirmadas e tratar mensagens repetidas com uma chave de idempotência.

Métricas

Nos planos Premium e Enterprise, a página do projeto mostra filas, mensagens prontas e sem confirmação, consumidores, taxas de publicação e de entrega e um aviso quando a memória está cheia. Mensagens sem confirmação que crescem indicam consumidores lentos ou sem ack.

Backups

O backup automático está incluído no plano, com restauração pelo suporte. Veja Backups automáticos.

O que o backup garante, até o último backup realizado:

  • as mensagens em filas persistentes (duráveis ou quorum);
  • a configuração: exchanges, filas, bindings, usuários e políticas.

O que não é garantido:

  • mensagens publicadas depois do último backup;
  • mensagens em filas não persistentes.

Para não perder mensagens, use filas duráveis, publique com persistent e confirmação de publicação e mantenha consumidores idempotentes.

Perguntas frequentes

Posso conectar sem TLS?

Não. Fora da Zenifra, somente amqps:// é aceito.

Posso instalar plugins ou abrir o painel de gerenciamento?

Não. Os plugins são definidos pela Zenifra e nenhum plugin opcional fica ligado, como shovel, federation, streams, MQTT, STOMP ou a exchange de mensagens atrasadas (delayed message); para atrasar uma entrega, use a entrega agendada. O painel de gerenciamento e a API HTTP do RabbitMQ não ficam expostos; use as métricas da página do projeto. Se a sua aplicação depende de um plugin, fale com o suporte.

Posso usar vários virtual hosts ou usuários?

A conexão fornecida usa o virtual host / e o usuário app.

O RabbitMQ garante entrega exactly-once?

Não. Como em qualquer RabbitMQ, a entrega é at-least-once: se a conexão cai depois que o consumidor recebeu a mensagem e antes de o ack chegar ao servidor, o servidor entrega a mensagem de novo, com redelivered marcado; e um produtor que reenvia uma publicação sem confirmação pode gravá-la duas vezes. Isso acontece em quedas de rede, reinícios e trocas de plano. Use uma chave de idempotência na aplicação para processar cada mensagem uma vez só.

Próximos passos

RabbitMQ® é uma marca da Broadcom, Inc. nos Estados Unidos e em outros países. A Zenifra não é afiliada à Broadcom nem endossada por ela.

Última atualização em

Nessa página