RabbitMQ: Darbo pradžia

Kaip naudotis Stackhero su RabbitMQ

Pažvelkime, kaip galite prijungti savo Python aplikaciją prie RabbitMQ naudodami Aio Pika biblioteką. Daugeliu atvejų, saugiam prisijungimui pakanka nurodyti AMQPS URL:

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

Toliau pateikiamas pilnas pavyzdys, kaip užmegzti saugų ryšį su RabbitMQ, sukurti kanalą ir deklaruoti bazinę eilę (queue). Tai puikus būdas patikrinti jūsų konfigūraciją:

import asyncio
import logging
import aio_pika

async def main() -> None:
    # Jei norite matyti debug žurnalus, galite atkomentuoti šią eilutę
    # 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())

Jei jungiantis iš Python gaunate tokią klaidą:

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

dažniausiai tai reiškia, kad jūsų sistemoje trūksta Let's Encrypt CA sertifikato. Norėdami tai išspręsti, įdiekite savo operacinei sistemai skirtą CA sertifikatų paketą:

  1. Ubuntu/Debian sistemose vykdykite:

    sudo apt install ca-certificates
    
  2. Alpine Linux sistemose vykdykite:

    apk add ca-certificates
    

Jei negalite naudoti šių komandų, vis dar galite įdiegti CA sertifikatą rankiniu būdu:

  1. Atsisiųskite Let's Encrypt CA sertifikatą iš https://letsencrypt.org/certs/isrgrootx1.pem.

  2. Tuomet Python kode jungiantis prie RabbitMQ nurodykite CA sertifikato failą:

    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
    )
    

Toliau pateikiamas pilnas pavyzdys, kaip naudoti Let's Encrypt CA sertifikatą saugiam prisijungimui:

import asyncio
import logging
import ssl
import aio_pika

async def main() -> None:
    # Norėdami įjungti debug žurnalus, galite atkomentuoti šią eilutę
    # logging.basicConfig(level=logging.DEBUG)

    ssl_context = ssl.create_default_context()
    # Įkelkite atsisiųstą Let's Encrypt CA sertifikatą
    # Pavyzdžiui: 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())

Jei norite jungtis prie RabbitMQ iš Go aplikacijos, oficiali Go RabbitMQ Client Library tai leidžia padaryti paprastai. Štai kaip galite pradėti:

  1. Sukurkite naują katalogą ir inicializuokite Go modulį:
go mod init rabbitmq-example
  1. Pridėkite RabbitMQ biblioteką prie savo projekto:
go get github.com/rabbitmq/amqp091-go
  1. Sukurkite failą main.go ir įdėkite šį kodą:

    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. Paleiskite savo kodą su:

go run main.go

Jei prisijungimas sėkmingas, pamatysite pranešimą "Successfully connected to RabbitMQ instance". Tai reiškia, kad prisijungėte saugiai, naudojant autentifikaciją ir TLS šifravimą.

Daugiau pavyzdžių rasite oficialiame RabbitMQ Go pavyzdžių repozitoriume: https://github.com/rabbitmq/rabbitmq-tutorials/tree/main/go.

Jei dirbate su PHP, galite naudoti php-amqplib biblioteką prisijungimui prie savo RabbitMQ instancijos. Kadangi Stackhero naudoja TLS (SSL) šifravimą, rekomenduojama naudoti 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);

Kartais jūsų TLS ryšiui gali prireikti Certificate Authority (CA) sertifikato. Daugelyje sistemų jis jau yra, tačiau jei reikia, galite jį atsisiųsti rankiniu būdu. Štai kaip tai padaryti:

  1. Atsisiųskite sertifikatą iš https://letsencrypt.org/certs/isrgrootx1.pem ir išsaugokite jį savo serveryje.
  2. Tuomet galite jungtis PHP naudodami atsisiųstą sertifikatą taip:
$sslOptions = array(
  'cafile' => realpath(__DIR__ . '/isrgrootx1.pem'),
);

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

Jei naudojate Symfony, galite jį sukonfigūruoti naudoti RabbitMQ kaip žinučių brokerį, nustatydami aplinkos kintamąjį MESSENGER_TRANSPORT_DSN. Pakanka atnaujinti savo .env failą:

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

Pakeiskite <USER>, <PASSWORD>, <HOST> ir <PORT> į savo RabbitMQ duomenis.

Toliau įsitikinkite, kad jūsų config/packages/messenger.yaml faile naudojamas MESSENGER_TRANSPORT_DSN kintamasis. Failas turėtų atrodyti taip:

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

Spring Boot aplikacijose galite sukonfigūruoti saugų prisijungimą prie Stackhero RabbitMQ instancijos atnaujindami savo aplikacijos nustatymus:

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

Jei kuriate su .NET ir MassTransit, štai kaip galite sukonfigūruoti savo projektą saugiam prisijungimui prie Stackhero RabbitMQ naudojant TLS šifravimą:

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

Jei jungiatės iš Elixir ir matote klaidos pranešimą

CLIENT ALERT: Fatal - Handshake Failure

dažniausiai tai rodo AMQP bibliotekos klaidą, susijusią su TLS 1.3 palaikymu. Patikimas sprendimas – priverstinai naudoti TLS 1.2, pridedant šią parinktį jungiantis:

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

Jei naudojant Node.js matote klaidą Error: Socket closed abruptly during opening handshake, tikėtina, kad naudojate amqplib bibliotekos versiją senesnę nei 0.10.7 kartu su RabbitMQ 4.1.0 ar naujesne. Šis pakeitimas susijęs su frame_max nustatymu, įvestu RabbitMQ 4.1.0 versijoje.

Norėdami išspręsti šią problemą, atnaujinkite savo amqplib biblioteką bent į 0.10.7 ar naujesnę versiją.