RabbitMQ: Iniziare

Come utilizzare Stackhero per RabbitMQ

👋 Benvenuti nella documentazione di Stackhero!

Stackhero offre una soluzione RabbitMQ cloud pronta all'uso che fornisce una serie di vantaggi, tra cui:

  • Accesso completo all'interfaccia web di RabbitMQ per gestire utenti, vhost e permessi.
  • Code illimitate senza limitazioni di tempo di conservazione.
  • Supporta i protocolli AMQP, MQTT, STOMP e WebSocket.
  • Molti plugin inclusi, come Delayed Message Exchange, Message Deduplication e Consistent-hash Exchange.
  • Aggiornamenti senza sforzo con un solo clic.
  • Prestazioni ottimali e sicurezza robusta grazie a una VM privata e dedicata.

Risparmia tempo e semplifica la tua vita: bastano 5 minuti per provare la soluzione di hosting cloud RabbitMQ di Stackhero!

Questo esempio mostra come utilizzare la libreria Aio Pika per connettere Python a RabbitMQ. In molti casi, specificare l'URL AMQPS è tutto ciò che serve:

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

Di seguito è riportato un esempio completo in Python che stabilisce una connessione sicura a RabbitMQ. È possibile seguire questi passaggi per verificare la connessione e impostare una coda di base:

import asyncio
import logging
import aio_pika

async def main() -> None:
    # Decommentare la riga seguente per abilitare i log di debug
    # 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("La connessione ha funzionato!")
        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())

Se si vede l'errore

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

quando ci si connette a RabbitMQ da Python, di solito indica che al sistema manca il certificato Let's Encrypt. Per risolvere questo problema, installare i certificati CA comuni:

  1. Su Ubuntu/Debian, eseguire:

    sudo apt install ca-certificates
    
  2. Su Alpine Linux, eseguire:

    apk add ca-certificates
    

Se non è possibile utilizzare questi comandi, è possibile installare manualmente il certificato CA:

  1. Scaricare il certificato CA Let's Encrypt da https://letsencrypt.org/certs/isrgrootx1.pem.

  2. Quindi, connettersi a RabbitMQ nel proprio codice Python passando il file del certificato 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
    )
    

Di seguito è riportato un esempio completo in Python che utilizza il certificato CA Let's Encrypt per stabilire una connessione sicura:

import asyncio
import logging
import ssl
import aio_pika

async def main() -> None:
    # Decommentare la riga seguente per abilitare i log di debug
    # logging.basicConfig(level=logging.DEBUG)

    ssl_context = ssl.create_default_context()
    # Caricare manualmente il certificato CA Let's Encrypt
    # Scaricarlo utilizzando: 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("La connessione ha funzionato!")
        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())

Di seguito è riportato un esempio semplice che mostra come connettersi a RabbitMQ da un'applicazione GoLang utilizzando la libreria ufficiale Go RabbitMQ Client Library. Seguire questi passaggi per configurare il progetto:

  1. Creare una nuova directory e inizializzare il modulo:
go mod init rabbitmq-example
  1. Aggiungere la libreria RabbitMQ:
go get github.com/rabbitmq/amqp091-go
  1. Creare un nuovo file denominato main.go e aggiungere il seguente contenuto:

    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("Connesso con successo all'istanza RabbitMQ")
    }
    
  2. Eseguire il codice:

go run main.go

Dovresti vedere "Connesso con successo all'istanza RabbitMQ", il che indica che il codice si è connesso in modo sicuro utilizzando l'autenticazione e la crittografia TLS.

Per ulteriori esempi, è possibile esplorare gli esempi Go nel repository ufficiale RabbitMQ: https://github.com/rabbitmq/rabbitmq-tutorials/tree/main/go.

Di seguito è riportato un esempio che dimostra come connettersi a RabbitMQ da PHP utilizzando la libreria php-amqplib. Poiché le istanze Stackhero utilizzano la crittografia TLS (SSL), la connessione deve essere stabilita con 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);

La connessione TLS potrebbe richiedere un certificato di autorità di certificazione (CA). Sebbene molti server lo abbiano già installato, potrebbe essere necessario scaricarlo manualmente. Seguire questi passaggi:

  1. Scaricare il certificato da https://letsencrypt.org/certs/isrgrootx1.pem e salvarlo sul server.
  2. Utilizzare il seguente codice PHP per connettersi utilizzando il certificato scaricato:
$sslOptions = array(
  'cafile' => realpath(__DIR__ . '/isrgrootx1.pem'),
);

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

Symfony può utilizzare RabbitMQ come broker di messaggi impostando la variabile di ambiente MESSENGER_TRANSPORT_DSN. Per configurare questo, modificare il file .env e impostare la variabile come segue:

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

Sostituire <USER>, <PASSWORD>, <HOST> e <PORT> con i dettagli di RabbitMQ.

Assicurarsi inoltre che il file config/packages/messenger.yaml utilizzi la variabile MESSENGER_TRANSPORT_DSN. La configurazione dovrebbe apparire così:

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

Di seguito è riportato un esempio di come configurare Spring Boot per connettersi in modo sicuro a un'istanza RabbitMQ Stackhero. Aggiornare le proprietà dell'applicazione con queste impostazioni:

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

Ecco un esempio che mostra come connettersi a Stackhero RabbitMQ utilizzando .NET e MassTransit. Questo esempio configura l'host con le impostazioni necessarie per la crittografia 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();
  }
}

Con il plugin "Messaggi ritardati", è possibile ritardare o programmare i messaggi impostando un ritardo in millisecondi. Il plugin può essere attivato direttamente dal dashboard Stackhero. Dopo aver attivato il plugin, creare uno scambio ritardato tramite il pannello di amministrazione RabbitMQ o direttamente nel codice.

Per ulteriori dettagli, consultare il repository ufficiale: https://github.com/rabbitmq/rabbitmq-delayed-message-exchange.

Se si disattiva il plugin, tutti i messaggi ritardati che non sono ancora stati consegnati andranno persi.

Dopo aver attivato il plugin sul dashboard Stackhero, accedere al pannello di amministrazione RabbitMQ e creare uno scambio di tipo "x-delayed-message". Aggiungere quindi un argomento con la chiave x-delayed-type e il valore "direct". Questa configurazione è illustrata nello screenshot qui sotto.

Creazione scambioCreazione scambio

Se si riscontra l'errore "Invalid argument, 'x-delayed-type' must be an existing exchange type", assicurarsi di aver impostato correttamente l'argomento x-delayed-type.

Quando si utilizza Elixir per connettersi a RabbitMQ, si potrebbe incontrare l'errore

CLIENT ALERT: Fatal - Handshake Failure

Questo problema è legato a un bug con il supporto TLS 1.3 nella libreria AMQP per Elixir. Una soluzione pratica è forzare l'uso di TLS 1.2. È possibile ottenere questo includendo la seguente opzione quando si apre la connessione:

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

L'errore Error: Socket closed abruptly during opening handshake può verificarsi quando si utilizza una versione della libreria amqplib di Node.js precedente alla 0.10.7 durante la connessione a RabbitMQ 4.1.0 o successivo. Questo problema è legato a una modifica nell'impostazione frame_max introdotta in RabbitMQ 4.1.0.

Per risolvere l'errore, aggiornare la libreria amqplib alla versione 0.10.7 o successiva.