RabbitMQ: Getting started

How to use Stackhero for RabbitMQ

Let us walk through how you can connect your Python application to RabbitMQ using the Aio Pika library. In most cases, you only need to provide the AMQPS URL for a secure connection:

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

Here is a complete example that shows how you can establish a secure connection to RabbitMQ, create a channel, and declare a basic queue. This is a great way to verify your setup:

import asyncio
import logging
import aio_pika

async def main() -> None:
    # If you want to see debug logs, you can uncomment the next line
    # 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())

If you encounter an error like this when connecting from Python:

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

it typically means your system is missing the Let's Encrypt CA certificate. To fix this, you can install the common CA certificates package for your operating system:

  1. On Ubuntu/Debian, you can run:

    sudo apt install ca-certificates
    
  2. On Alpine Linux, you can run:

    apk add ca-certificates
    

If you are unable to use these commands, you still have the option to install the CA certificate manually:

  1. Download the Let's Encrypt CA certificate from https://letsencrypt.org/certs/isrgrootx1.pem.

  2. Then, you can connect to RabbitMQ in your Python code by specifying the CA certificate file:

    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
    )
    

Here is a full example using the Let's Encrypt CA certificate for secure connections:

import asyncio
import logging
import ssl
import aio_pika

async def main() -> None:
    # To enable debug logs, you can uncomment this line
    # logging.basicConfig(level=logging.DEBUG)

    ssl_context = ssl.create_default_context()
    # Load the Let's Encrypt CA certificate you downloaded
    # For example: 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())

If you would like to connect to RabbitMQ from a Go application, the official Go RabbitMQ Client Library makes it straightforward. Here is how you can get started:

  1. Create a new directory and initialize your Go module:
go mod init rabbitmq-example
  1. Next, you can add the RabbitMQ library to your project:
go get github.com/rabbitmq/amqp091-go
  1. Now, create a file named main.go and add this 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. You can run your code with:

go run main.go

If your connection is successful, you should see the message "Successfully connected to RabbitMQ instance". This means you are connected securely using authentication and TLS encryption.

For more detailed examples, you might want to check out the Go examples in the official RabbitMQ repository: https://github.com/rabbitmq/rabbitmq-tutorials/tree/main/go.

If you are working with PHP, you can use the php-amqplib library to connect to your RabbitMQ instance. Since Stackhero uses TLS encryption (SSL), you will want to use 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);

Sometimes, your TLS connection might require a Certificate Authority (CA) certificate. While many systems already include this, you can manually download it if needed. Here is how:

  1. Download the certificate from https://letsencrypt.org/certs/isrgrootx1.pem and save it on your server.
  2. Then, you can connect using PHP with the downloaded certificate as follows:
$sslOptions = array(
  'cafile' => realpath(__DIR__ . '/isrgrootx1.pem'),
);

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

If you are using Symfony, you can configure it to use RabbitMQ as a message broker by setting the MESSENGER_TRANSPORT_DSN environment variable. You only need to update your .env file:

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

Replace <USER>, <PASSWORD>, <HOST>, and <PORT> with your own RabbitMQ details.

Next, make sure your config/packages/messenger.yaml file uses the MESSENGER_TRANSPORT_DSN variable. It should look something like this:

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

For Spring Boot applications, you can set up a secure connection to your Stackhero RabbitMQ instance by updating your application properties:

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

If you are developing with .NET and MassTransit, here is how you can configure your project to connect securely to Stackhero RabbitMQ using TLS encryption:

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

If you are connecting from Elixir and see the error message

CLIENT ALERT: Fatal - Handshake Failure

this usually points to a bug in the AMQP library's support for TLS 1.3. A reliable workaround is to force the use of TLS 1.2 by including this option when opening the connection:

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

If you see the error Error: Socket closed abruptly during opening handshake when using Node.js, it is likely because you are using a version of the amqplib library older than 0.10.7 with RabbitMQ 4.1.0 or later. This change relates to the frame_max setting introduced in RabbitMQ 4.1.0.

To resolve this, you can update your amqplib library to version 0.10.7 or newer.