Todos los productos
Search
Centro de documentos

Simple Message Queue (formerly MNS):Distribución de mensajes de un productor a varios consumidores

Última actualización: Sep 04, 2026

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.

Nota

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:

  1. Cree un tema y una cola por cada consumidor.

  2. Suscriba cada cola al tema. El endpoint de la cola se convierte en el destino de la suscripción.

  3. El productor publica un mensaje en el tema.

  4. SMQ copia el mensaje en cada cola suscrita.

  5. 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:

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

topicMeta

Metadatos del tema (nombre, propiedades).

queueNameList

Lista de nombres de colas. Cada cola recibe una copia de cada mensaje publicado.

needCreateQueue

Indica si se deben crear las colas listadas en queueNameList. Establezca este valor en true para crearlas automáticamente.

queueMetaTemplate

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 CloudAccount

Autentica la solicitud con su AccessKey ID, AccessKey Secret y el endpoint de SMQ.

Llamar a createPullTopic

Crea el tema, genera las tres colas de consumidores y suscribe cada cola al tema.

Llamar a publishMessage

Publica un mensaje sin procesar (RawTopicMessage) en el tema. SMQ lo copia en todas las colas suscritas.

Llamar a popMessage(30)

Cada consumidor obtiene su copia con un tiempo de espera de sondeo largo de 30 segundos.

Llamar a pullTopic.delete()

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 con getMessageBodyAsRawString() . Si usa Base64TopicMessage en su lugar, analícelos con getMessageBodyAsString() .

Pasos siguientes