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.
| Plano | Nós | Tipo de fila padrão | Métricas |
|---|---|---|---|
queue-starter | 1 | clássica | não |
queue-basic | 3, com alta disponibilidade | quorum | não |
queue-premium | 3, com alta disponibilidade | quorum | sim |
queue-enterprise | 3, com alta disponibilidade | quorum | sim |
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. A troca de plano não está disponível para o RabbitMQ; 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 amqplibimport 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 pikaimport 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 comoorders.*) efanout(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
ackdepois de processar; comnacksem 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 comnacksem reenfileirar ou expiradas vão para a exchange indicada.
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.
Limites por plano
| Plano | Conexões | Canais por conexão | Canais no total | Tamanho máximo da mensagem | Tamanho máximo da fila |
|---|---|---|---|---|---|
queue-starter | 100 | 128 | 400 | 4 MiB | 128 MiB |
queue-basic | 300 | 256 | 1.200 | 16 MiB | 256 MiB |
queue-premium | 1.000 | 512 | 3.000 | 16 MiB | 512 MiB |
queue-enterprise | 5.000 | 1.024 | 12.000 | 16 MiB | 2 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.
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 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. A entrega é at-least-once; use uma chave de idempotência na aplicação.
Próximos passos
Última atualização em
Filas com Valkey: Streams e Pub/Sub
Filas com motor Valkey: Streams, consumer groups, confirmação, recuperação de pendências, Pub/Sub e exemplos em Node.js e Python.
Armazém: armazenamento de objetos
Guarde imagens, vídeos, backups e outros arquivos no Armazém da Zenifra, com buckets privados, chaves por aplicação e links que expiram.