Simple Message Queue (SMQ, anteriormente MNS) admite un patrón combinado de tema y cola: un tema distribuye cada mensaje publicado a varias colas mediante push, y los consumidores obtienen los mensajes de sus propias colas privadas. Este tutorial implementa dicha arquitectura de distribución con el SDK de Java de SMQ.
Este tutorial usa el SDK para Java. Para consultar los SDK en otros lenguajes, consulte Reference for New Version SDKs (Recommended).
Comparación de modelos de mensajería
SMQ ofrece dos modelos base de mensajería. La elección adecuada depende de cómo reciben los mensajes los consumidores, si es posible exponer sus endpoints y si se requiere una entrega selectiva.
|
Modelo |
Funcionamiento |
Visibilidad del consumidor |
Filtrado de mensajes |
Recomendado para |
|
Basado en colas |
Un cliente envía mensajes a una cola. Varios consumidores obtienen mensajes, pero cada mensaje llega solo a uno de ellos. |
Los endpoints permanecen privados |
No compatible |
Distribución de tareas punto a punto |
|
Basado en temas |
Un cliente publica mensajes en un tema. SMQ envía los mensajes a todos los consumidores suscritos. |
Los endpoints deben estar expuestos |
Compatible mediante filtros de suscripción |
Notificaciones push en tiempo real |
|
Combinado (este tutorial) |
Un cliente publica en un tema. El tema envía mensajes a varias colas. Cada consumidor obtiene los mensajes de su propia cola. |
Los endpoints permanecen privados |
Compatible mediante filtros de suscripción |
Distribución con consumidores privados |
El patrón combinado es adecuado para escenarios donde un mensaje debe llegar a varios consumidores cuyos endpoints no pueden exponerse; por ejemplo, consumidores que se ejecutan dentro de una red privada.
Escenario de ejemplo: Un sistema de procesamiento de pedidos publica cada nuevo pedido en un tema. Colas independientes alimentan los servicios de cumplimiento, análisis y notificaciones. Cada servicio obtiene los pedidos de su propia cola de forma independiente, sin necesidad de exponer un endpoint de entrada.
Funcionamiento
El patrón combinado conecta un tema con varias colas a través de suscripciones. Una suscripción actúa como una cola virtual: recibe una copia de cada mensaje publicado en el tema, y los consumidores obtienen los mensajes de ella exactamente como lo harían de una cola normal.
La configuración sigue estos pasos:
Cree un tema y una cola por cada consumidor.
Suscriba cada cola al tema. El endpoint de la cola se convierte en el destino de la suscripción.
El productor publica un mensaje en el tema.
SMQ copia el mensaje en cada cola suscrita.
Cada consumidor obtiene su copia de su propia cola.

Dado que los consumidores obtienen los mensajes de las colas en lugar de recibirlos mediante push, sus endpoints nunca quedan expuestos ante SMQ ni entre sí.
Requisitos previos
Antes de empezar, asegúrese de contar con lo siguiente:
IntelliJ IDEA o Eclipse instalado (este tutorial usa IntelliJ IDEA)
JDK 1.8 o posterior
Apache Maven 2.5 o posterior
Instalación de la dependencia de Java
Agregue la dependencia del SDK de SMQ al archivo pom.xml de su proyecto de Java:
<dependencies>
<dependency>
<groupId>com.aliyun.mns</groupId>
<artifactId>aliyun-sdk-mns</artifactId>
<version>1.1.9.2</version>
</dependency>
</dependencies>
Referencia de la API CloudPullTopic
SDK for Java 1.1.8 introdujo la clase CloudPullTopic, que encapsula el patrón combinado de tema y cola. Cree un objeto CloudPullTopic mediante MNSClient:
// Full form: create queues automatically with a queue metadata template
public CloudPullTopic createPullTopic(
TopicMeta topicMeta,
Vector<String> queueNameList,
boolean needCreateQueue,
QueueMeta queueMetaTemplate
)
// Short form: use existing queues (no automatic creation)
public CloudPullTopic createPullTopic(
TopicMeta topicMeta,
Vector<String> queueNameList
)
|
Parámetro |
Descripción |
|
|
Metadatos del tema (nombre, propiedades). |
|
|
Lista de nombres de colas. Cada cola recibe una copia de cada mensaje publicado. |
|
|
Indica si se deben crear las colas listadas en |
|
|
Plantilla de metadatos de cola que se aplica a todas las colas creadas automáticamente (por ejemplo, tiempo de espera de sondeo). |
Publicación y consumo de mensajes
El siguiente ejemplo usa CloudPullTopic para configurar la distribución, publicar un mensaje y obtenerlo de tres colas independientes.
package doc;
import com.aliyun.mns.client.CloudAccount;
import com.aliyun.mns.client.MNSClient;
import com.aliyun.mns.client.CloudPullTopic;
import com.aliyun.mns.client.CloudQueue;
import com.aliyun.mns.model.QueueMeta;
import com.aliyun.mns.model.TopicMeta;
import com.aliyun.mns.model.TopicMessage;
import com.aliyun.mns.model.RawTopicMessage;
import com.aliyun.mns.model.Message;
import com.aliyun.mns.common.ServiceException;
import com.aliyun.mns.common.ClientException;
import java.util.Vector;
public class DemoTopicMessageBroadcast {
public static void main(String[] args) {
// Initialize the client with your AccessKey ID, AccessKey Secret, and endpoint.
CloudAccount account = new CloudAccount(
ServiceSettings.getMNSAccessKeyId(),
ServiceSettings.getMNSAccessKeySecret(),
ServiceSettings.getMNSAccountEndpoint());
MNSClient client = account.getMNSClient();
// Define three consumer queues.
Vector<String> consumerNameList = new Vector<String>();
String consumerName1 = "consumer001";
String consumerName2 = "consumer002";
String consumerName3 = "consumer003";
consumerNameList.add(consumerName1);
consumerNameList.add(consumerName2);
consumerNameList.add(consumerName3);
// Set long polling to 30 seconds for the auto-created queues.
QueueMeta queueMetaTemplate = new QueueMeta();
queueMetaTemplate.setPollingWaitSeconds(30);
try {
// --- Producer: create a topic and publish a message ---
String topicName = "demo-topic-for-pull";
TopicMeta topicMeta = new TopicMeta();
topicMeta.setTopicName(topicName);
// createPullTopic creates the topic, creates the three consumer queues,
// and subscribes each queue to the topic — all in one call.
CloudPullTopic pullTopic = client.createPullTopic(
topicMeta, consumerNameList, true, queueMetaTemplate);
// Publish a raw message to the topic. SMQ copies it into all subscribed queues.
String messageBody = "broadcast message to all the consumers:hello the world.";
TopicMessage tMessage = new RawTopicMessage();
tMessage.setBaseMessageBody(messageBody);
pullTopic.publishMessage(tMessage);
// --- Consumers: pull the message from each queue ---
CloudQueue queueForConsumer1 = client.getQueueRef(consumerName1);
CloudQueue queueForConsumer2 = client.getQueueRef(consumerName2);
CloudQueue queueForConsumer3 = client.getQueueRef(consumerName3);
// popMessage(30) waits up to 30 seconds for a message (long polling).
Message consumer1Msg = queueForConsumer1.popMessage(30);
if (consumer1Msg != null) {
System.out.println("consumer1 received: "
+ consumer1Msg.getMessageBodyAsRawString());
} else {
System.out.println("consumer1 queue is empty");
}
Message consumer2Msg = queueForConsumer2.popMessage(30);
if (consumer2Msg != null) {
System.out.println("consumer2 received: "
+ consumer2Msg.getMessageBodyAsRawString());
} else {
System.out.println("consumer2 queue is empty");
}
Message consumer3Msg = queueForConsumer3.popMessage(30);
if (consumer3Msg != null) {
System.out.println("consumer3 received: "
+ consumer3Msg.getMessageBodyAsRawString());
} else {
System.out.println("consumer3 queue is empty");
}
// Clean up: delete the topic, its subscriptions, and all associated queues.
pullTopic.delete();
} catch (ClientException ce) {
System.out.println("Network error between the client and SMQ. "
+ "Check your network and DNS settings.");
ce.printStackTrace();
} catch (ServiceException se) {
se.printStackTrace();
}
client.close();
}
}
Comprobación del resultado
Después de ejecutar el ejemplo, confirme que cada consumidor recibió el mensaje. Salida esperada:
consumer1 received: broadcast message to all the consumers:hello the world.
consumer2 received: broadcast message to all the consumers:hello the world.
consumer3 received: broadcast message to all the consumers:hello the world.
Si una cola muestra "queue is empty", es posible que el mensaje aún no se haya entregado. Aumente el tiempo de espera de popMessage o compruebe que el tema y las suscripciones se crearon correctamente.
Explicación del código
|
Paso |
Acción realizada |
|
Inicializar |
Autentica la solicitud con su AccessKey ID, AccessKey Secret y el endpoint de SMQ. |
|
Llamar a |
Crea el tema, genera las tres colas de consumidores y suscribe cada cola al tema. |
|
Llamar a |
Publica un mensaje sin procesar ( |
|
Llamar a |
Cada consumidor obtiene su copia con un tiempo de espera de sondeo largo de 30 segundos. |
|
Llamar a |
Elimina el tema, sus suscripciones y todas las colas asociadas. |
El ejemplo publica un mensaje sin procesar (RawTopicMessage). Analice sintácticamente los mensajes sin procesar congetMessageBodyAsRawString(). Si usaBase64TopicMessageen su lugar, analícelos congetMessageBodyAsString().
Pasos siguientes
Explore otros patrones de mensajería de SMQ en Reference for New Version SDKs (Recommended).