RabbitMQ: Premiers pas

Comment utiliser Stackhero pour RabbitMQ

Voyons ensemble comment connecter votre application Python à RabbitMQ en utilisant la bibliothèque Aio Pika. Dans la plupart des cas, il suffit de fournir l'URL AMQPS pour établir une connexion sécurisée :

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

Voici un exemple complet qui montre comment établir une connexion sécurisée à RabbitMQ, créer un channel et déclarer une file de base. C'est une excellente façon de vérifier votre configuration :

import asyncio
import logging
import aio_pika

async def main() -> None:
    # Si vous souhaitez afficher les logs de debug, vous pouvez décommenter la ligne suivante
    # 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 vous rencontrez une erreur de ce type lors de la connexion depuis Python :

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

cela signifie généralement que le certificat CA Let's Encrypt manque sur votre système. Pour corriger cela, installez le paquet de certificats CA adapté à votre système d'exploitation :

  1. Sur Ubuntu/Debian, exécutez :

    sudo apt install ca-certificates
    
  2. Sur Alpine Linux, exécutez :

    apk add ca-certificates
    

Si vous ne pouvez pas utiliser ces commandes, vous pouvez aussi installer le certificat CA manuellement :

  1. Téléchargez le certificat CA Let's Encrypt depuis https://letsencrypt.org/certs/isrgrootx1.pem.

  2. Ensuite, connectez-vous à RabbitMQ dans votre code Python en spécifiant le fichier du certificat 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
    )
    

Voici un exemple complet utilisant le certificat CA Let's Encrypt pour des connexions sécurisées :

import asyncio
import logging
import ssl
import aio_pika

async def main() -> None:
    # Pour activer les logs de debug, vous pouvez décommenter cette ligne
    # logging.basicConfig(level=logging.DEBUG)

    ssl_context = ssl.create_default_context()
    # Chargez le certificat CA Let's Encrypt que vous avez téléchargé
    # Par exemple : 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())

Pour connecter une application Go à RabbitMQ, la Go RabbitMQ Client Library officielle simplifie la démarche. Voici comment commencer :

  1. Créez un nouveau dossier et initialisez votre module Go :
go mod init rabbitmq-example
  1. Ajoutez ensuite la bibliothèque RabbitMQ à votre projet :
go get github.com/rabbitmq/amqp091-go
  1. Créez maintenant un fichier nommé main.go et ajoutez ce code :

    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. Exécutez votre code avec :

go run main.go

Si la connexion fonctionne, vous verrez le message "Successfully connected to RabbitMQ instance". Cela signifie que vous êtes connecté de façon sécurisée avec authentification et chiffrement TLS.

Pour des exemples plus avancés, consultez les exemples Go du dépôt officiel RabbitMQ : https://github.com/rabbitmq/rabbitmq-tutorials/tree/main/go.

Si vous développez en PHP, la bibliothèque php-amqplib permet de se connecter à votre instance RabbitMQ. Stackhero utilisant le chiffrement TLS (SSL), il est recommandé d'utiliser 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);

Dans certains cas, votre connexion TLS peut nécessiter un certificat d'autorité de certification (CA). De nombreux systèmes l'incluent déjà, mais vous pouvez le télécharger manuellement si besoin. Voici comment procéder :

  1. Téléchargez le certificat depuis https://letsencrypt.org/certs/isrgrootx1.pem et enregistrez-le sur votre serveur.
  2. Ensuite, connectez-vous en PHP en utilisant le certificat téléchargé comme suit :
$sslOptions = array(
  'cafile' => realpath(__DIR__ . '/isrgrootx1.pem'),
);

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

Si vous utilisez Symfony, vous pouvez le configurer pour utiliser RabbitMQ comme message broker en définissant la variable d'environnement MESSENGER_TRANSPORT_DSN. Il suffit de mettre à jour votre fichier .env :

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

Remplacez <USER>, <PASSWORD>, <HOST> et <PORT> par vos propres informations RabbitMQ.

Ensuite, vérifiez que votre fichier config/packages/messenger.yaml utilise bien la variable MESSENGER_TRANSPORT_DSN. Il doit ressembler à ceci :

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

Pour les applications Spring Boot, configurez une connexion sécurisée à votre instance RabbitMQ Stackhero en mettant à jour vos propriétés d'application :

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 vous développez avec .NET et MassTransit, voici comment configurer votre projet pour se connecter de façon sécurisée à Stackhero RabbitMQ avec chiffrement 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 vous vous connectez depuis Elixir et voyez le message d'erreur

CLIENT ALERT: Fatal - Handshake Failure

cela indique généralement un bug dans la gestion de TLS 1.3 par la bibliothèque AMQP. Une solution fiable consiste à forcer l'utilisation de TLS 1.2 en ajoutant cette option lors de l'ouverture de la connexion :

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

Si vous voyez l'erreur Error: Socket closed abruptly during opening handshake en utilisant Node.js, cela provient probablement de l'utilisation d'une version de la bibliothèque amqplib antérieure à 0.10.7 avec RabbitMQ 4.1.0 ou supérieur. Ce changement est lié au paramètre frame_max introduit dans RabbitMQ 4.1.0.

Pour corriger ce problème, mettez à jour votre bibliothèque amqplib vers la version 0.10.7 ou plus récente.