1. Información general
El desacoplamiento de componentes de software es una de las partes más importantes del diseño de software. Una forma de lograrlo es utilizar sistemas de mensajería, que proporcionan una forma asincrónica de comunicación entre componentes (servicios). En este artículo, cubriremos uno de estos sistemas: RabbitMQ.
RabbitMQ es un agente de mensajes que implementa el Protocolo de cola de mensajes avanzado (AMQP). Proporciona bibliotecas cliente para los principales lenguajes de programación.
Además de utilizar para desacoplar componentes de software, RabbitMQ se puede utilizar para:
- Realización de operaciones en segundo plano
- Realización de operación asincrónica
2. Modelo de mensajería
Primero, echemos un vistazo rápido y de alto nivel a cómo funciona la mensajería.
En pocas palabras, hay dos tipos de aplicaciones que interactúan con un sistema de mensajería: productores y consumidores. Los productores son aquellos que envían (publican) mensajes a un corredor, y los consumidores, quienes reciben mensajes del corredor. Por lo general, estos programas (componentes de software) se ejecutan en diferentes máquinas y RabbitMQ actúa como un middleware de comunicación entre ellos.
En este artículo, discutiremos un ejemplo simple con dos servicios que se comunicarán usando RabbitMQ. Uno de los servicios publicará mensajes en RabbitMQ y el otro consumirá.
3. Configuración
Para empezar, ejecutemos RabbitMQ usando la guía de configuración oficial aquí.
Naturalmente, usaremos el cliente Java para interactuar con el servidor RabbitMQ; la dependencia de Maven para este cliente es:
com.rabbitmq amqp-client 4.0.0
Después de ejecutar el corredor RabbitMQ usando la guía oficial, necesitamos conectarnos a él usando el cliente java:
ConnectionFactory factory = new ConnectionFactory(); factory.setHost("localhost"); Connection connection = factory.newConnection(); Channel channel = connection.createChannel();
Usamos ConnectionFactory para configurar la conexión con el servidor, se encarga del protocolo (AMQP) y la autenticación también. Aquí nos conectamos al servidor en localhost , podemos modificar el nombre del host usando la función setHost .
Podemos usar setPort para configurar el puerto si el servidor RabbitMQ no usa el puerto predeterminado; el puerto predeterminado para RabbitMQ es 15672 :
factory.setPort(15678);
Podemos configurar el nombre de usuario y la contraseña:
factory.setUsername("user1"); factory.setPassword("MyPassword");
Además, usaremos esta conexión para publicar y consumir mensajes.
4. Productor
Considere un escenario simple donde una aplicación web permite a los usuarios agregar nuevos productos a un sitio web. Siempre que se agregue un nuevo producto, debemos enviar un correo electrónico a los clientes.
Primero, definamos una cola:
channel.queueDeclare("products_queue", false, false, false, null);
Cada vez que los usuarios agreguen un nuevo producto, publicaremos un mensaje en una cola:
String message = "product details"; channel.basicPublish("", "products_queue", null, message.getBytes());
Por último, cerramos el canal y la conexión:
channel.close(); connection.close();
Este mensaje será consumido por otro servicio, que se encarga de enviar correos electrónicos a los clientes.
5. Consumidor
Veamos qué podemos implementar del lado del consumidor; vamos a declarar la misma cola:
channel.queueDeclare("products_queue", false, false, false, null);
Así es como definimos el consumidor que procesará los mensajes de la cola de forma asincrónica:
DefaultConsumer consumer = new DefaultConsumer(channel) { @Override public void handleDelivery( String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException { String message = new String(body, "UTF-8"); // process the message } }; channel.basicConsume("products_queue", true, consumer);
6. Conclusión
Este artículo simple cubrió conceptos básicos de RabbitMQ y discutió un ejemplo simple de su uso.
La implementación completa de este tutorial se puede encontrar en el proyecto GitHub.