RabbitMQ: Primeros pasos

Cómo utilizar Stackhero para RabbitMQ

A continuación le mostramos cómo puede conectar su aplicación Python a RabbitMQ utilizando la librería Aio Pika. En la mayoría de los casos, solo necesita proporcionar la URL AMQPS para establecer una conexión segura:

connection = await aio_pika.connect_robust(
  "amqps://admin:<PASSWORD>@<XXXXXX>.stackhero-network.com:<AMQP_PORT_TLS>",
)

Aquí tiene un ejemplo completo que muestra cómo establecer una conexión segura con RabbitMQ, crear un canal y declarar una cola básica. Es una excelente manera de verificar su configuración:

import asyncio
import logging
import aio_pika

async def main() -> None:
    # Si desea ver logs de depuración, puede descomentar la siguiente línea
    # logging.basicConfig(level=logging.DEBUG)

    connection = await aio_pika.connect_robust(
        "amqps://admin:<PASSWORD>@<XXXXXX>.stackhero-network.com:<AMQP_PORT_TLS>"
    )

    async with connection:
        print("The connection worked!")
        channel = await connection.channel()
        await channel.set_qos(prefetch_count=10)
        queue = await channel.declare_queue("test_queue", auto_delete=True)

if __name__ == "__main__":
    asyncio.run(main())

Si encuentra un error como este al conectarse desde Python:

aiormq.exceptions.AMQPConnectionError: [Errno 5] [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)

normalmente significa que a su sistema le falta el certificado CA de Let's Encrypt. Para solucionarlo, puede instalar el paquete de certificados CA correspondiente a su sistema operativo:

  1. En Ubuntu/Debian, ejecute:

    sudo apt install ca-certificates
    
  2. En Alpine Linux, ejecute:

    apk add ca-certificates
    

Si no puede utilizar estos comandos, también tiene la opción de instalar el certificado CA manualmente:

  1. Descargue el certificado CA de Let's Encrypt desde https://letsencrypt.org/certs/isrgrootx1.pem.

  2. Después, puede conectarse a RabbitMQ en su código Python especificando el archivo del certificado CA:

    import ssl
    
    ssl_context = ssl.create_default_context()
    ssl_context.load_verify_locations(cafile='isrgrootx1.pem')
    
    connection = await aio_pika.connect_robust(
      "amqps://admin:<PASSWORD>@<XXXXXX>.stackhero-network.com:<AMQP_PORT_TLS>",
      ssl_context=ssl_context
    )
    

Aquí tiene un ejemplo completo utilizando el certificado CA de Let's Encrypt para conexiones seguras:

import asyncio
import logging
import ssl
import aio_pika

async def main() -> None:
    # Para habilitar los logs de depuración, puede descomentar esta línea
    # logging.basicConfig(level=logging.DEBUG)

    ssl_context = ssl.create_default_context()
    # Cargue el certificado CA de Let's Encrypt que ha descargado
    # Por ejemplo: wget https://letsencrypt.org/certs/isrgrootx1.pem
    ssl_context.load_verify_locations(cafile='isrgrootx1.pem')

    connection = await aio_pika.connect_robust(
        "amqps://admin:<PASSWORD>@<XXXXXX>.stackhero-network.com:<AMQP_PORT_TLS>",
        ssl_context=ssl_context
    )

    async with connection:
        print("The connection worked!")
        channel = await connection.channel()
        await channel.set_qos(prefetch_count=10)
        queue = await channel.declare_queue("test_queue", auto_delete=True)

if __name__ == "__main__":
    asyncio.run(main())

Si desea conectar una aplicación Go a RabbitMQ, la Go RabbitMQ Client Library oficial lo hace muy sencillo. Así es como puede empezar:

  1. Cree un nuevo directorio e inicialice su módulo Go:
go mod init rabbitmq-example
  1. A continuación, añada la librería RabbitMQ a su proyecto:
go get github.com/rabbitmq/amqp091-go
  1. Ahora, cree un archivo llamado main.go y añada este código:

    package main
    
    import (
      "fmt"
      amqp "github.com/rabbitmq/amqp091-go"
    )
    
    func main() {
      connection, err := amqp.Dial("amqps://<PASSWORD>@<XXXXXX>.stackhero-network.com:<AMQP_PORT_TLS>")
      if err != nil {
        panic(err)
      }
      defer connection.Close()
    
      fmt.Println("Successfully connected to RabbitMQ instance")
    }
    
  2. Puede ejecutar su código con:

go run main.go

Si la conexión es exitosa, verá el mensaje "Successfully connected to RabbitMQ instance". Esto significa que está conectado de forma segura utilizando autenticación y cifrado TLS.

Para ejemplos más avanzados, puede consultar los ejemplos de Go en el repositorio oficial de RabbitMQ: https://github.com/rabbitmq/rabbitmq-tutorials/tree/main/go.

Si trabaja con PHP, puede utilizar la librería php-amqplib para conectarse a su instancia de RabbitMQ. Como Stackhero utiliza cifrado TLS (SSL), debe usar AMQPSSLConnection:

use PhpAmqpLib\Connection\AMQPSSLConnection;

$connection = new AMQPSSLConnection(
  '<XXXXXX>.stackhero-network.com',
  <AMQP_PORT_TLS>,
  'admin',
  '<PASSWORD>',
  '/',
  array()
);

/**
 * @param \PhpAmqpLib\Connection\AbstractConnection $connection
 */
function shutdown($connection)
{
  $connection->close();
}

register_shutdown_function('shutdown', $connection);

En ocasiones, su conexión TLS puede requerir un certificado de Autoridad de Certificación (CA). Aunque muchos sistemas ya lo incluyen, puede descargarlo manualmente si es necesario. Así es como puede hacerlo:

  1. Descargue el certificado desde https://letsencrypt.org/certs/isrgrootx1.pem y guárdelo en su servidor.
  2. Después, puede conectarse usando PHP con el certificado descargado de la siguiente manera:
$sslOptions = array(
  'cafile' => realpath(__DIR__ . '/isrgrootx1.pem'),
);

$connection = new AMQPSSLConnection(
  '<XXXXXX>.stackhero-network.com',
  <AMQP_PORT_TLS>,
  'admin',
  '<PASSWORD>',
  '/',
  $sslOptions
);

Si utiliza Symfony, puede configurarlo para usar RabbitMQ como message broker estableciendo la variable de entorno MESSENGER_TRANSPORT_DSN. Solo tiene que actualizar su archivo .env:

MESSENGER_TRANSPORT_DSN=amqps://<USER>:<PASSWORD>@<HOST>:<PORT>/%2f/messages?cacert=%2Fetc%2Fssl%2Fcerts%2Fca-certificates.crt

Sustituya <USER>, <PASSWORD>, <HOST> y <PORT> por los datos de su instancia de RabbitMQ.

A continuación, asegúrese de que su archivo config/packages/messenger.yaml utilice la variable MESSENGER_TRANSPORT_DSN. Debería tener un aspecto similar a este:

framework:
    messenger:
        transports:
            async: '%env(MESSENGER_TRANSPORT_DSN)%'

Para aplicaciones Spring Boot, puede configurar una conexión segura a su instancia de RabbitMQ en Stackhero actualizando las propiedades de su aplicación:

spring.rabbitmq.host=<XXXXXX>.stackhero-network.com
spring.rabbitmq.port=<AMQP_PORT_TLS>
spring.rabbitmq.username=admin
spring.rabbitmq.password=<PASSWORD>
spring.rabbitmq.ssl.enabled=true
spring.rabbitmq.ssl.algorithm=TLSv1.2

Si desarrolla con .NET y MassTransit, así puede configurar su proyecto para conectarse de forma segura a Stackhero RabbitMQ utilizando cifrado TLS:

using MassTransit;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;

public class Program
{
  public static void Main(string[] args)
  {
    var host = Host.CreateDefaultBuilder(args)
      .ConfigureServices((context, services) =>
      {
        services.AddMassTransit(x =>
        {
          x.UsingRabbitMq((context, cfg) =>
          {
            cfg.Host(new Uri("amqps://admin:<PASSWORD>@<XXXXXX>.stackhero-network.com:<AMQP_PORT_TLS>"), h =>
            {
              h.UseSsl(s =>
              {
                s.Protocol = System.Security.Authentication.SslProtocols.Tls12;
              });
            });
          });
        });

        services.AddMassTransitHostedService(true);
      })
      .Build();

    host.Run();
  }
}

Si se conecta desde Elixir y ve el mensaje de error

CLIENT ALERT: Fatal - Handshake Failure

esto suele indicar un bug en el soporte de TLS 1.3 de la librería AMQP. Una solución fiable es forzar el uso de TLS 1.2 incluyendo esta opción al abrir la conexión:

AMQP.Connection.open("amqps://admin:<PASSWORD>@<XXXXXX>.stackhero-network.com:<AMQP_PORT_TLS>", :undefined, ssl_options: [ versions: [ :"tlsv1.2" ] ])

Si ve el error Error: Socket closed abruptly during opening handshake al utilizar Node.js, probablemente se deba a que está usando una versión de la librería amqplib anterior a la 0.10.7 con RabbitMQ 4.1.0 o superior. Este cambio está relacionado con el parámetro frame_max introducido en RabbitMQ 4.1.0.

Para solucionarlo, actualice su librería amqplib a la versión 0.10.7 o superior.