【rabbitmq】(七)发布订阅模式

一、fanout(发布订阅模式)
为了说明发布/订阅模式,我们构建一个简单的日志系统。它有两个程序组成,第一个程序是发出日志消息,第二个程序是消费者。我们启动两个消费者,其中一个消费者接收到消息后把日志存储在磁盘,另一个消费者接收到消息后把消息打印在屏幕上,实际上第一个程序发出的日志消息将广播给所有消费者。
1、fanout,是将接收到的所有消息广播到它知道的所有队列中。系统中默认有些exchange类型
在这里插入图片描述
1、1实战
交换机会将消息广播给与他有binging关系的队列,以工不同的消费者使用。
在这里插入图片描述
Logs交换机和临时队列的绑定关系如下:
在这里插入图片描述

在这里插入图片描述
发布订阅模式,生产者通过交换机以广播的形式将消息发布出去,与交换机有binding关系的的队列接收到消息后,各个消费者消费其对应队列中的消息。
代码:
生产者:

package com.example.rabbitmq.five;


import com.example.rabbitmq.rabbitMqUtils.RabbitUtils;
import com.rabbitmq.client.Channel;

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

// 发消息 交换机
public class EmitLogs {
    // 交换机的名称
    private static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws IOException, TimeoutException {
        Channel channel = RabbitUtils.getChannel();
        // 声明交换机,fanout表示发布订阅模式
        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()) {
            String message = scanner.next();
            /*
             * 发送一个消息
             * 1、发送到哪个交换机
             * 2、路由routing key是哪个,本次binding 可以使用空串
             * 3、其他参数信息
             * 4、发送消息的消息体
             * */
            channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes());
            System.out.println("生产者发出消息:" + message);
        }
    }
}

消费者1

package com.example.rabbitmq.five;


import com.example.rabbitmq.rabbitMqUtils.RabbitUtils;
import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

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

/**
 * 交换机:发布订阅模式
 * ReceiveLog01将接收到的消息打印在控制台
 **/
public class ReceiveLog01 {
    // 交换机的名称
    private static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws IOException, TimeoutException {
        Channel channel = RabbitUtils.getChannel();
        // 声明一个交换机
        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
        // 声明一个临时队列
        /**
         * 生成一个临时队列,名称随机
         * 当消费之断开与队列的链接时候,临时队列就会自动删除
         *
         * */
        String queueName = channel.queueDeclare().getQueue();
        /**
         * 绑定交换机与队列
         *
         * */
        channel.queueBind(queueName, EXCHANGE_NAME, "");// routingkey可以是空串
        System.out.println("ReceiveLog01等待接收消息,把接收到的消息打印在控制台输出......");
        // 接收消息
        DeliverCallback deliverCallback = (consumeTag, message) -> {
            System.out.println("ReceiveLog01控制台打印接收到的消息:" + new String(message.getBody()));
        };

        // 消费者取消消息时回调接口
        CancelCallback cancelCallback = (consumerTag) -> {
            System.out.println(consumerTag + "消息者取消消费回调逻辑");
        };

        channel.basicConsume(queueName, true, deliverCallback, cancelCallback);

    }
}

消费者2

package com.example.rabbitmq.five;

import com.example.rabbitmq.rabbitMqUtils.RabbitUtils;
import com.rabbitmq.client.CancelCallback;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DeliverCallback;

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

public class ReceiveLog02 {
    // 交换机的名称
    private static final String EXCHANGE_NAME = "logs";

    public static void main(String[] args) throws IOException, TimeoutException {
        Channel channel = RabbitUtils.getChannel();
        // 声明一个交换机
        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
        // 声明一个临时队列
        /**
         * 生成一个临时队列,名称随机
         * 当消费之断开与队列的链接时候,临时队列就会自动删除
         *
         * */
        String queueName = channel.queueDeclare().getQueue();
        /**
         * 绑定交换机与队列
         *
         * */
        channel.queueBind(queueName, EXCHANGE_NAME, "");// routingkey可以是空串
        System.out.println("ReceiveLog02等待接收消息,把接收到的消息打印在控制台输出......");
        // 接收消息
        DeliverCallback deliverCallback = (consumeTag, message) -> {
            System.out.println("ReceiveLog02控制台打印接收到的消息:" + new String(message.getBody()));
        };

        // 消费者取消消息时回调接口
        CancelCallback cancelCallback = (consumerTag) -> {
            System.out.println(consumerTag + "消息者取消消费回调逻辑");
        };

        channel.basicConsume(queueName, true, deliverCallback, cancelCallback);

    }
}

生产者发布消息,通过交换机广播出去,消费者01和02都接收到消息:

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值