Ocho, RabbitMQ de temas (Temas)

En primer lugar, el modelo

diagrama de Temas modelo

  • P (Productor): Fabricante - Enviar mensaje
  • X (Exchange): Switch - Aceptar mensaje enviado por el productor, por un lado, por el contrario el mensaje push a la cola
  • Q (cola): una cola de mensajes (figura rojo cuadrados) - mensaje almacenado
  • C (consumidor): Consumidores - Recibir mensajes 
  • Encuadernación: Bind - relación entre el interruptor y la cola de unión
  • Enrutamiento clave: claves de enrutamiento - tener este mensaje y propiedad de enlace, los mensajes interruptor de empuje, se encontrará en consonancia con la cola de mensajes de enrutamiento botón de empuje en las colas que están atados junto

    Temas (Temas): envían un mensaje , así como interruptores y cola de unión son necesarios para establecer la relación fundamental de encaminamiento automático y fijaciones (unión) de enrutamiento de comodines de apoyo clave , después de que el productor envía un mensaje al interruptor, el interruptor de colas que están obligados a encontrar enrutamiento llaves del enrutamiento de mensajes claves para que coincida con la cola para el mensaje push. Si no hay ninguna coincidencia, entonces el mensaje se pierde.

通配符说明:

*:匹配一个字符
#:匹配一个或多个字符


注意:
1、若队列与交换机的Binding中Routing Key不包含*和#,则表示相等队列推送,类似于直连交换机(Direct Exchange);
2、若队列与交换机的Binding中Routing Key为#或#.#,则表示全部队列推送,类似于扇形交换机(Fanout Exchange)。

    modelo de interpretación

  • La unión entre el interruptor y la cola fundamentales están fijados a la auto-enrutamiento, y el encaminamiento contenida comodines clave de soporte de unión;
  • El mensaje en sí también necesita configurar teclas de enrutamiento;
  • Cuando el interruptor para encaminar un mensaje de autenticación de claves y claves de enrutamiento de mensajes push unión en fase de adaptación empujará.

    Nota: El modo de enrutamiento (Routing) necesidad de interruptor (Exchange) tipo se define como "tema".

Dos, Tema Exchange (interruptor de tema)

    1, modelo

Tema diagrama de modelo de interruptor

    2, significado 

    Interruptor tema (Tema Exchange) se verá en toda su relación vinculante de acuerdo con el mensaje llevado por el encaminamiento (Routing teclas clave), y encaminar los mensajes clave que coinciden con la cola para empujar el mensaje.

   3, diferente del selector de dirección (Intercambio Directo) de

    3.1, selector de dirección, la relación vinculante clave de enrutamiento de cola y el interruptor no es compatible con comodines, pero el tema de los interruptores de apoyo;

    3,2, interruptor de dirección, el mensaje tiene que ser empujado a la cola de mensajes claves de vinculación idéntica de encaminamiento, pero el tema es el caso interruptor relativa línea de coincidencia comodín.

Tres, de programación Java

    1, tarro introducido paquete de protocolo AMQP, y la creación de conexión RabbitMQ herramientas, consulte tres, la cola RabbitMQ sencillo (el simple Queue) ;

    2, crear mensaje enviado por el productor;

package com.rabbitMQ.topic;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitMQ.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

/**
 * 主题模式-生产者
 * *:代表一个任意字符
 * #:代表一个或多个任意字符
 * @author zhoujin
 * @data 2019-1-23
 */
public class TopicProducer {
	
	private static final String EXCHANGE_NAME = "exchange_topic";
	
	private static final String TOPIC_ERROR = "message.error";
	private static final String ERROR_MESSAGE = "This is topic MQ, routing key is message.error!";
	
	private static final String TOPIC_INFO = "message.info";
	private static final String INFO_MESSAGE = "This is topic MQ, routing key is message.info!";

	public static void main(String[] args) {
		Connection conn = null;
		Channel channel = null;
		try {
			// 1.获取连接
			conn = ConnectionUtils.getConnection();
			// 2.从连接中获取通道
			channel = conn.createChannel();
			// 3.声明交换机
			channel.exchangeDeclare(EXCHANGE_NAME, "topic");
			// 4.发送消息
			String message = ERROR_MESSAGE;
			channel.basicPublish(EXCHANGE_NAME, TOPIC_ERROR, null, message.getBytes());
			System.out.println("======================= Topic MQ send message end! 【Content:" + message + "】 =======================");
			
			message = INFO_MESSAGE;
			channel.basicPublish(EXCHANGE_NAME, TOPIC_INFO, null, message.getBytes());
			System.out.println("======================= Topic MQ send message end! 【Content:" + message + "】 =======================");
			
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			e.printStackTrace();
		} finally {
			// 7.关闭连接
			try {
				ConnectionUtils.closeConnection(channel, conn);
			} catch (IOException e) {
				e.printStackTrace();
			} catch (TimeoutException e) {
				e.printStackTrace();
			}
		}
	}
	
}

   3. Crear un consumidor 1 recibe un mensaje;

package com.rabbitMQ.topic;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitMQ.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;

/**
 * 主题模式-第一个消费者
 * *:代表一个任意字符
 * #:代表一个或多个任意字符
 * @author zhoujin
 * @data 2019-1-23
 */
public class TopicFirstConsumer {
	
	private static final String QUEUE_NAME = "queue_topic_first";
	private static final String EXCHANGE_NAME = "exchange_topic";
	
	public static void main(String[] args) {
		try {
			// 1.获取连接
			Connection conn = ConnectionUtils.getConnection();
			// 2.从连接中获取通道
			final Channel channel = conn.createChannel();
			// 3.声明队列
			channel.queueDeclare(QUEUE_NAME, false, false, false, null);
			// 4.将队列绑定到交换机上
			channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "#.info");
			// 5.保证一次只接收一条消息
			channel.basicQos(1);
			// 6.创建消费者
			DefaultConsumer consumer = new DefaultConsumer(channel){
				
				@Override
				public void handleDelivery(String consumerTag,
						Envelope envelope, BasicProperties properties,
						byte[] body) throws IOException {

					String message = new String(body, "UTF-8");
					System.out.println("======================= First topic(#.info) consumer received a message! 【Content:" + message + "】 =======================");
					
					// 休眠,模拟业务处理
					try {
						Thread.sleep(2000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					} finally {
						// 7.手动发送反馈回执
						channel.basicAck(envelope.getDeliveryTag(), false);
					}
					
				}
				
			};
			// 8.监听队列(关闭自动反馈,即第二个参数为false)
			channel.basicConsume(QUEUE_NAME, false, consumer);
			
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			e.printStackTrace();
		}
	}

}

    4. Crear una Consumidor 2 recibe el mensaje.

package com.rabbitMQ.topic;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import com.rabbitMQ.util.ConnectionUtils;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import com.rabbitmq.client.AMQP.BasicProperties;

/**
 * 主题模式-第二个消费者
 * *:代表一个任意字符
 * #:代表一个或多个任意字符
 * @author zhoujin
 * @data 2019-1-23
 */
public class TopicSecondConsumer {
	
	private static final String QUEUE_NAME = "queue_topic_second";
	private static final String EXCHANGE_NAME = "exchange_topic";
	
	public static void main(String[] args) {
		try {
			// 1.获取连接
			Connection conn = ConnectionUtils.getConnection();
			// 2.从连接中获取通道
			final Channel channel = conn.createChannel();
			// 3.声明队列
			channel.queueDeclare(QUEUE_NAME, false, false, false, null);
			// 4.将队列绑定到交换机上
			channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "message.#");
			// 5.保证一次只接收一条消息
			channel.basicQos(1);
			// 6.创建消费者
			DefaultConsumer consumer = new DefaultConsumer(channel){
				
				@Override
				public void handleDelivery(String consumerTag,
						Envelope envelope, BasicProperties properties,
						byte[] body) throws IOException {
					
					String message = new String(body, "UTF-8");
					System.out.println("======================= Second topic(message.#) consumer received a message! 【Content:" + message + "】 =======================");
					
					// 休眠,模拟业务处理
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					} finally {
						// 7.手动发送反馈回执
						channel.basicAck(envelope.getDeliveryTag(), false);
					}
					
				}
				
			};
			// 8.监听队列(关闭自动反馈,即第二个参数为)
			channel.basicConsume(QUEUE_NAME, false, consumer);
			
		} catch (IOException e) {
			e.printStackTrace();
		} catch (TimeoutException e) {
			e.printStackTrace();
		}
	}

}

    Nota: Si el único productor en el código conmutadores definidos, pero que no están definidos en la cola del consumidor o cola definida pero con el cambio a bind, compilar y ejecutar el programa no se les está dando, pero se perderán el mensaje. Debido a que el interruptor no tiene la capacidad de almacenar mensajes, RabbitMQ sólo tiene la capacidad de almacenar los mensajes en la cola.

En cuarto lugar, ejecute el código de salida y la consola

    1, Run código del productor - define el interruptor;

    ① ¿Por qué aquí que tenga que ejecutar el productor código?

        Debido a que es necesario definir el interruptor en el productor. Si el consumidor se inicia primero, se le solicita error de error de "no cambio" porque el interruptor no está definida!

    ② por qué el mensaje enviado por el productor pierde?

        Sin embargo, debido a las colas que están atados, y el interruptor en sí no tiene una función de almacenar el mensaje, y por lo tanto conducen a la pérdida de mensajes.

    2, la ejecución de dos código consumidor;

    2.1, consulte la cola en la página web de gestión de información vinculante;

página Web para ver la cola de gestión de la información vinculante

    3, código del productor correr de nuevo - el envío de un mensaje.

    3.1, los productores de salida de la consola;

salida de la consola Productor

    3.2, la salida de la consola primer consumidor (# .info);

El primer consumidor (# .info) salida de la consola

    3.3, el segundo consumidor (mensaje. #) Salida de la consola

El segundo de los consumidores (mensaje. #) Salida de la consola

 


Publicado 47 artículos originales · elogios ganado 16 · Vistas a 70000 +

Supongo que te gusta

Origin blog.csdn.net/zorro_jin/article/details/86658977
Recomendado
Clasificación