RabbitMQ: Erste Schritte

Wie man Stackhero für RabbitMQ verwendet

👋 Willkommen in der Stackhero-Dokumentation!

Stackhero bietet eine einsatzbereite RabbitMQ-Cloud-Lösung, die zahlreiche Vorteile bietet, darunter:

  • Voller Zugriff auf die RabbitMQ-Weboberfläche zur Verwaltung von Benutzern, vhosts und Berechtigungen.
  • Unbegrenzte Warteschlangen ohne Einschränkungen bei der Aufbewahrungszeit.
  • Unterstützung der Protokolle AMQP, MQTT, STOMP und WebSocket.
  • Viele Plugins enthalten, wie Delayed Message Exchange, Message Deduplication und Consistent-hash Exchange.
  • Mühelose Updates mit nur einem Klick.
  • Optimale Leistung und robuste Sicherheit durch eine private und dedizierte VM.

Sparen Sie Zeit und vereinfachen Sie Ihr Leben: Es dauert nur 5 Minuten, um die RabbitMQ-Cloud-Hosting-Lösung von Stackhero auszuprobieren!

Dieses Beispiel zeigt, wie die Aio Pika Bibliothek verwendet wird, um Python mit RabbitMQ zu verbinden. In vielen Fällen reicht es aus, die AMQPS-URL anzugeben:

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

Unten finden Sie ein vollständiges Python-Beispiel, das eine sichere Verbindung zu RabbitMQ herstellt. Sie können diese Schritte befolgen, um Ihre Verbindung zu überprüfen und eine grundlegende Warteschlange einzurichten:

import asyncio
import logging
import aio_pika

async def main() -> None:
    # Kommentieren Sie die folgende Zeile aus, um Debug-Logs zu aktivieren
    # 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("Die Verbindung hat funktioniert!")
        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())

Wenn Sie den Fehler sehen

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

beim Verbinden mit RabbitMQ von Python aus, deutet dies normalerweise darauf hin, dass Ihr System das Let's Encrypt-Zertifikat fehlt. Um dies zu beheben, installieren Sie die gängigen CA-Zertifikate:

  1. Auf Ubuntu/Debian führen Sie aus:

    sudo apt install ca-certificates
    
  2. Auf Alpine Linux führen Sie aus:

    apk add ca-certificates
    

Wenn Sie diese Befehle nicht verwenden können, können Sie das CA-Zertifikat manuell installieren:

  1. Laden Sie das Let's Encrypt CA-Zertifikat von https://letsencrypt.org/certs/isrgrootx1.pem herunter.

  2. Verbinden Sie sich dann in Ihrem Python-Code mit RabbitMQ, indem Sie die CA-Zertifikatsdatei übergeben:

    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
    )
    

Unten finden Sie ein vollständiges Python-Beispiel, das das Let's Encrypt CA-Zertifikat verwendet, um eine sichere Verbindung herzustellen:

import asyncio
import logging
import ssl
import aio_pika

async def main() -> None:
    # Kommentieren Sie die folgende Zeile aus, um Debug-Logs zu aktivieren
    # logging.basicConfig(level=logging.DEBUG)

    ssl_context = ssl.create_default_context()
    # Laden Sie das Let's Encrypt CA-Zertifikat manuell
    # Laden Sie es herunter mit: 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("Die Verbindung hat funktioniert!")
        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())

Unten finden Sie ein einfaches Beispiel, das zeigt, wie man sich von einer GoLang-Anwendung aus mit RabbitMQ verbindet, indem die offizielle Go RabbitMQ Client Library verwendet wird. Folgen Sie diesen Schritten, um Ihr Projekt einzurichten:

  1. Erstellen Sie ein neues Verzeichnis und initialisieren Sie das Modul:
go mod init rabbitmq-example
  1. Fügen Sie die RabbitMQ-Bibliothek hinzu:
go get github.com/rabbitmq/amqp091-go
  1. Erstellen Sie eine neue Datei namens main.go und fügen Sie den folgenden Inhalt hinzu:

    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("Erfolgreich mit RabbitMQ-Instanz verbunden")
    }
    
  2. Führen Sie Ihren Code aus:

go run main.go

Sie sollten "Erfolgreich mit RabbitMQ-Instanz verbunden" sehen, was anzeigt, dass Ihr Code sicher mit Authentifizierung und TLS-Verschlüsselung verbunden ist.

Für weitere Beispiele können Sie die Go-Beispiele im offiziellen RabbitMQ-Repository erkunden: https://github.com/rabbitmq/rabbitmq-tutorials/tree/main/go.

Unten finden Sie ein Beispiel, das zeigt, wie man sich von PHP aus mit RabbitMQ verbindet, indem die php-amqplib Bibliothek verwendet wird. Da Stackhero-Instanzen TLS-Verschlüsselung (SSL) verwenden, muss die Verbindung mit AMQPSSLConnection hergestellt werden:

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);

Die TLS-Verbindung erfordert möglicherweise ein Zertifikat einer Zertifizierungsstelle (CA). Obwohl viele Server dies bereits installiert haben, müssen Sie es möglicherweise manuell herunterladen. Folgen Sie diesen Schritten:

  1. Laden Sie das Zertifikat von https://letsencrypt.org/certs/isrgrootx1.pem herunter und speichern Sie es auf Ihrem Server.
  2. Verwenden Sie den folgenden PHP-Code, um sich mit dem heruntergeladenen Zertifikat zu verbinden:
$sslOptions = array(
  'cafile' => realpath(__DIR__ . '/isrgrootx1.pem'),
);

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

Symfony kann RabbitMQ als Nachrichtenbroker verwenden, indem die Umgebungsvariable MESSENGER_TRANSPORT_DSN gesetzt wird. Um dies zu konfigurieren, bearbeiten Sie die .env-Datei und setzen Sie die Variable wie folgt:

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

Ersetzen Sie <USER>, <PASSWORD>, <HOST> und <PORT> durch Ihre RabbitMQ-Details.

Stellen Sie außerdem sicher, dass die Datei config/packages/messenger.yaml die Variable MESSENGER_TRANSPORT_DSN verwendet. Die Konfiguration sollte so aussehen:

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

Unten finden Sie ein Beispiel, wie Sie Spring Boot konfigurieren können, um sich sicher mit einer Stackhero RabbitMQ-Instanz zu verbinden. Aktualisieren Sie Ihre Anwendungseigenschaften mit diesen Einstellungen:

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

Hier ist ein Beispiel, das zeigt, wie man sich mit Stackhero RabbitMQ unter Verwendung von .NET und MassTransit verbindet. Dieses Beispiel konfiguriert den Host mit den notwendigen Einstellungen für die TLS-Verschlüsselung:

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();
  }
}

Mit dem "Delayed messages"-Plugin können Sie Nachrichten verzögern oder planen, indem Sie eine Verzögerung in Millisekunden festlegen. Das Plugin kann direkt über das Stackhero-Dashboard aktiviert werden. Nachdem Sie das Plugin aktiviert haben, erstellen Sie entweder über das RabbitMQ-Admin-Panel oder direkt in Ihrem Code einen verzögerten Exchange.

Für weitere Details siehe das offizielle Repository: https://github.com/rabbitmq/rabbitmq-delayed-message-exchange.

Wenn Sie das Plugin deaktivieren, gehen alle verzögerten Nachrichten, die noch nicht zugestellt wurden, verloren.

Nachdem Sie das Plugin im Stackhero-Dashboard aktiviert haben, navigieren Sie zu Ihrem RabbitMQ-Admin-Panel und erstellen Sie einen Exchange vom Typ "x-delayed-message". Fügen Sie dann ein Argument mit dem Schlüssel x-delayed-type und dem Wert "direct" hinzu. Diese Einrichtung wird im folgenden Screenshot veranschaulicht.

Exchange-ErstellungExchange-Erstellung

Wenn Sie den Fehler "Invalid argument, 'x-delayed-type' must be an existing exchange type" erhalten, stellen Sie sicher, dass Sie das Argument x-delayed-type korrekt gesetzt haben.

Wenn Sie Elixir verwenden, um sich mit RabbitMQ zu verbinden, könnten Sie den Fehler

CLIENT ALERT: Fatal - Handshake Failure

Dieser Fehler hängt mit einem Bug in der TLS 1.3-Unterstützung in der AMQP-Bibliothek für Elixir zusammen. Eine praktische Lösung besteht darin, die Verwendung von TLS 1.2 zu erzwingen. Dies erreichen Sie, indem Sie die folgende Option beim Öffnen der Verbindung einfügen:

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

Der Fehler Error: Socket closed abruptly during opening handshake kann auftreten, wenn Sie eine Version der Node.js amqplib-Bibliothek verwenden, die älter als 0.10.7 ist, während Sie sich mit RabbitMQ 4.1.0 oder später verbinden. Dieses Problem hängt mit einer Änderung der frame_max-Einstellung zusammen, die in RabbitMQ 4.1.0 eingeführt wurde.

Um den Fehler zu beheben, aktualisieren Sie Ihre amqplib-Bibliothek auf Version 0.10.7 oder höher.