Publicar mensaje en RabbitMQ con Golang (parte 1)

Hace poco tiempo que trabajo con colas de RabbitMQ, como cualquier otra mecanismo asíncrono tiene sus pros y contras.

Como cualquier otra tecnología, tendemos a acuñarla y aplicarla en absolutamente todos los niveles de negocio, obviando muchas veces alternativas más adecuadas y eficiente. Muchas veces cayendo en anti patrones, como puede ser el MQ over Batch (obviamente cuanto tiene sentido).

Por otro lado, también tenemos alternativas como pueden ser pub/sub. La aplicación de pub/sub o MQ depende de cómo escalará la aplicación y que tenemos que “ceder”, para usar uno u otro. Espero hablar de esto en un post con más detalle.

Repositorio

Si os sirve de ayuda el código en el repositorio una estrellita no estaría de más

Enlace: Github repo (Golang)

Publicar mensajes RabbitMQ con GO

En este post sólo pondremos la parte de publicación de un mesare con go y seguramente en una parte 2, pondremos como consumir estos msg.

La estructura del proyecto, como sólo tiene este pequeño ejemplo es bastante simple:

Hablando de dependencia

Para esta pequeña aplicación, tan sólo necesitamos la dependencia de: github.com/streadway/amqp, que nos ofrece la gestión de conexiones, colas, publicación y consumo entre otras cosas.

module apascualco.com/rabbitmq-publisher-example
go 1.15
require github.com/streadway/amqp v1.0.0

Nuestro fichero main

El ejemplo es bastante sencillo y he evitado poner excesivo ruido para que sea practico al entender o utilizar en vuestro proyecto.

package main
import (
"log"
"time"
"github.com/streadway/amqp"
)
const QUEUE = "example_task_queue"
func connectRabbitMQ() *amqp.Connection {
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/apascualco")
if err != nil {
log.Fatalf("Failed to connect to RabbitMQ: %s", err)
}
return conn
}
func openChannel(conn *amqp.Connection) *amqp.Channel {
c, err := conn.Channel()
if err != nil {
log.Fatalf("Failed to open a channel: %s", err)
}
return c
}
func declareQueue(channel *amqp.Channel) amqp.Queue {
q, err := channel.QueueDeclare(QUEUE, true, false, false, false, nil)
if err != nil {
log.Fatalf("Failed to declare a queue: %s", err)
}
return q
}
func publish(text string, channel *amqp.Channel, queue amqp.Queue) {
err := channel.Publish(
"",
queue.Name,
false,
false,
amqp.Publishing{
DeliveryMode: amqp.Persistent,
ContentType:  "text/plain",
Body:         []byte(text),
})
if err != nil {
log.Fatalf("Failed to publish a message: %s", err)
}
}
func generateMessages(count int) {
n := 0
for n < count {
n++ 
publish("apascualco : "+time.Now().String(),.channel,.queue)¬
}
}
func main() {
conn := connectRabbitMQ()
defer conn.Close()
channel := openChannel(conn)
defer channel.Close()
queue := declareQueue(channel)
publish("apascualco: "+time.Now().String(), channel, queue)
}

Si veis, la función main, podéis ver los pasos que se siguen para hacer la publicación:

  • Obtener la conexión de rabbit
  • Abrir un canal con la conexión obtenida
  • Declarar una cola
  • Publicar msg

How to use it

Para comprobar el funcionamiento, primero tenemos que tener un RabbitMQ, corriendo y acceso a el (para validar de forma más cómoda que se publica el msg).

Para ello, he añadido en el repo un Docker compone que levantara un rabbit y su herramienta de administración. Para lanzarlo tan solo tenéis que lanzar el comando

docker-composer up -d

Esto, nos levantará on Docker con el rabbit, preparado para ser utilizado. Podéis comprobarlo de la siguiente manera:

Si no os funciona el ejemplo por lo menos tenéis un RabbitMQ en local :).

Una vez que tenemos la infra necesaria, construimos el ejecutable lanzando y luego lo ejecutas:

go build cmd/publish_example.go
./publish_example

Esto provocará que si entramos en nuestro RabbitMQ, seguramente en la dirección: http://localhost:15672 (guest/guest)

Ya hemos publicado nuestro primer msg!

CategoriesGO

Deja una respuesta

A %d blogueros les gusta esto: