RabbitMq 发布订阅 Publish/Subscribe fanout/direct

目录

 

概述

交换机

临时队列

代码


概述

在上篇中了解到rabbitmq 生产者生产消息到队列,多个消费者可以接受。这篇文章主要记录广播类型为fanout。生产者不在将产生的消息发送到队列,而是将消息发送到交换机exchange,交换机会根据不同的交换规则,将消息发送到不同的队列。交换器必须知道她所接收的消息是什么?它应该将消息放到哪个队列中或者还是应该丢弃?这些规则都是按照交换机的规则来确定的。

           

交换机

Exchange(交换机):生产者会将消息发送到交换机,然后交换机通过路由策略(规则)将消息路由到匹配的队列中去

交换规则:

Fanout 不处理路由。需要简单的将队列绑定到交换机上。一个发送到该类型交换机的消息都会被广播到与该交换机绑定的所有队列上。(本篇文章)

direct:它会把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中。

channel.basicPublish(“direct”, “warn”, MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());

我们定义direct交换机,绑定路由warn 这时候发送消息只能发送的绑定的队列中 如队列1 队列2 但是如果绑定路由为info 则只有队列2可以收到。

topic:direct类型的Exchange路由规则是完全匹配binding key与routing key,但这种严格的匹配方式在很多情况下不能满足实际业务需求。topic类型的Exchange在匹配规则上进行了扩展,它与direct类型的Exchage相似。

定义

//参数1 名称 参数2 类型
channel.exchangeDeclare("fanout", "fanout");

临时队列

在生产者和消费者之间创建一个新的队列,这时候又不想使用原来的队列,临时队列就是为这个场景而生的:

首先,每当我们连接到RabbitMQ,我们需要一个新的空队列,我们可以用一个随机名称来创建,或者说让服务器选择一个随机队列名称给我们,一旦我们断开消费者,队列应该立即被删除。

在Java客户端,提供queuedeclare()为我们创建一个非持久化、独立、自动删除的队列名称。

队列绑定

 BindOk com.rabbitmq.client.Channel.queueBind(String queue, String exchange, String routingKey) throws IOException


Bind a queue to an exchange, with no extra arguments.

Parameters:
      queue the name of the queue
      exchange the name of the exchange
      routingKey the routine key to use for the binding
Returns:
      a binding-confirm method if the binding was successfully created
Throws:
       java.io.IOException - if an error is encountered

代码

该代码为fanout模式

生产者

package com.ll.mq.hellomq.queue;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * 
 * @author ll 生产者
 *
 */
public class Producer {

	private static final String EXCHANGE_NAME = "fanoutStudy";

    public static void main(String[] argv) throws Exception {

        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("127.0.0.1");
		factory.setPort(5672);
		factory.setUsername("kysc");
		factory.setPassword("123456");
        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");

//      分发消息
        for(int i = 0 ; i < 5; i++){
            String message = "Hello World! " + i;
             channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
             System.out.println(" send'" + message + "'");
        }
        channel.close();
        connection.close();
    }

}

消费者1

package com.ll.mq.hellomq.fanout;

import java.io.IOException;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
/**
 * 
 * @author ll 消费者1
 *
 */
public class ConsumerOne {

	private static final String EXCHANGE_NAME = "fanoutStudy";

	public static void main(String[] argv) throws Exception {
		ConnectionFactory factory = new ConnectionFactory();
		factory.setHost("localhost");
		factory.setPort(5672);
		factory.setUsername("kysc");
		factory.setPassword("123456");
		Connection connection = factory.newConnection();
		Channel channel = connection.createChannel();
		// 声明交换机类型
		channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
		// 获取临时队列
		String queueName = channel.queueDeclare().getQueue();
		// 绑定
		channel.queueBind(queueName, EXCHANGE_NAME, "");

		System.out.println(" [*] Waiting for messages");

		Consumer 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");
				System.out.println("  ConsumerOne '" + message + "'");
			}
		};
		channel.basicConsume(queueName, true, consumer);
	}
}

消费者2

package com.ll.mq.hellomq.fanout;

import java.io.IOException;

import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Consumer;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;

public class ConsumerTwo {

	
	 private static final String EXCHANGE_NAME = "fanoutStudy";

	    public static void main(String[] argv) throws Exception {
	        ConnectionFactory factory = new ConnectionFactory();
	        factory.setHost("127.0.0.1");
	    	factory.setPort(5672);
			factory.setUsername("kysc");
			factory.setPassword("123456");
	        Connection connection = factory.newConnection();
	        Channel channel = connection.createChannel();
	        //声明交换机类型
	        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
	        //获取临时队列
	        String queueName = channel.queueDeclare().getQueue();
	        //绑定
	        channel.queueBind(queueName, EXCHANGE_NAME, "");

	        System.out.println(" [*] Waiting for messages");

	        Consumer 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");
	                System.out.println(" ConsumerTwo '" + message + "'");
	            }
	        };
	        channel.basicConsume(queueName, true, consumer);
	    }
}

结果:

生产者: send'Hello World! 0'
               send'Hello World! 1'
               send'Hello World! 2'
               send'Hello World! 3'
               send'Hello World! 4'

消费者1    ConsumerOne 'Hello World! 0'
               ConsumerOne 'Hello World! 1'
               ConsumerOne 'Hello World! 2'
              ConsumerOne 'Hello World! 3'
              ConsumerOne 'Hello World! 4'

消费者2   ConsumerTwo'Hello World! 0'
               ConsumerTwo'Hello World! 1'
               ConsumerTwo'Hello World! 2'
              ConsumerTwo'Hello World! 3'
              ConsumerTwo'Hello World! 4'

rabbitmq结果:

 

下一篇 https://blog.csdn.net/lilongwangyamin/article/details/105117288 rabbitmq topic

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值