RabbitMQ五种消息模式

介绍: 

Rabbit总共用6种消息模式,基本消息模式,工作模式,发布订阅模式,路由模式,主题模式,还有最后一种就是RPC,所有消息模式都是基于 基本消息模式进行的 :关于基本消息模式可以看我上一篇博客:https://blog.csdn.net/gloamer/article/details/118436062?spm=1001.2014.3001.5501

 工作模式:

基本消息模式 就是说 一个消息生产者 一个消息队列 一个消息消费者,但消息过多,消费不过来,可能会导致消息堆积,所以当一个消费者消费不过来的时候我们就可以用多个消息消费者进行消费从而解决这个问题 这就是咱们的工作模式

工作模式与基本消息模式很类型 浅意上来讲就是多了几个消息消费者 ,下面是对比图:

基本消息模式:

RabbitMQ五种消息模式_第1张图片

工作模式:

RabbitMQ五种消息模式_第2张图片

根据这两张图片的对比可以看的出来区别,操作其实也没有变化 只要再多Copy几份消费者就好啦

发布订阅模式:

RabbitMQ五种消息模式_第3张图片

 如图所示,发布订阅模式是在工作模式的基础之上添加了一个消息转换器,然后根据消息生产者和消息队列之间经过了一个消息交换器(Exchange)再与消息队列进行绑定,消息队列再绑定消息消费者竟然 咱们的消费者绑定的是消息队列 也就是说咱们的消费者代码也可以不做改动,后面的模式也是一样,但消息转换器是有类型的只需关心咱们的消息生产者就好啦。

生产者永远不会直接向队列发送任何消息。实际上,很多时候,生产者甚至根本不知道消息是否会被传递到任何队列。
相反,生产者只能向交换器发送消息。交换是一件很简单的事情。一方面它接收来自生产者的消息,另一方面它将消息推送到队列。交换器必须确切地知道如何处理接收到的消息。它应该被附加到特定的队列中吗?它应该附加到许多队列中吗?或者它应该被丢弃。的规则

解释了这么多,不如直接看代码来的实在:

package com.shenwang.rabbit.fanout;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.shenwang.rabbit.util.RabbitConnectionUtil;

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

/**
 * @author: shenwang
 * Date: 2021/7/5
 */
public class FanoutSend {
    public static final String EXCHANGE_NAME="exchange_queue";
    public static void main(String[] args){
        try {
            //建立连接
            Connection connection = RabbitConnectionUtil.getConnection();
            //创建频道
            Channel channel = connection.createChannel();
            /**
             * 声明转换器
             * 参数1:转换器名称
             * 参数2:类型 广播类型
             */
            channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.FANOUT);
            //声明多个队列
            channel.queueDeclare("queue_name1",true,false,false,null);
            channel.queueDeclare("queue_name2",true,false,false,null);
            //将队列与队列进行绑定
            channel.queueBind("queue_name1",EXCHANGE_NAME,"");
            channel.queueBind("queue_name1",EXCHANGE_NAME,"");
            //消息发布
            String message="Publish/Subscrib!!";
            channel.basicPublish(EXCHANGE_NAME,"",null,message.getBytes());
            //关闭
            channel.close();
            connection.close();
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

结果解释:

这里我们需要和工作模式做一个对比,工作模式是分配消息举个列子: 

假如咱们发布了8条消息,那咱们消费者1拿到的可能是1,2,5,6消费者2拿到的可能是3,4,7,8 而我们的发布订阅模式是谁都可以收到咱们的消息 

路由模式:

RabbitMQ五种消息模式_第4张图片

发布订阅模式向所有消费者广播所有消息。我们希望对其进行扩展,以允许根据消息的严重性进行过滤。例如,我们可能希望将日志消息写入磁盘的程序只接收关键错误,而不将磁盘空间浪费在警告或信息日志消息上。
我们使用的是扇出交换,这没有给我们太多的灵活性——它只能进行盲目的广播。
我们将使用直接交换代替。直接交换背后的路由算法很简单——消息发送到绑定键精确的队列

package com.shenwang.rabbit.routingkey;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.shenwang.rabbit.util.RabbitConnectionUtil;

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

/**
 * @author: shenwang
 * Date: 2021/7/5
 */
public class RoutingKeySend {
    public static final String EXCHANGE_NAME="exchange_routingKey_queue";
    public static void main(String[] args) throws IOException, TimeoutException {
        //建立连接
        Connection connection= RabbitConnectionUtil.getConnection();
        //创建连接
        Channel channel = connection.createChannel();
        /**
         * 声明交换机
         * 参数1:交换机名称
         * 参数2:交换机类型
         */
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT);
        //声明多个队列
        channel.queueDeclare("queue_rotingkey1",true,false,false,null);
        channel.queueDeclare("queue_rotingkey1",true,false,false,null);
        //交换机与队列进行绑定
        channel.queueBind("queue_rotingkey1",EXCHANGE_NAME,"insert");
        channel.queueBind("queue_rotingkey2",EXCHANGE_NAME,"update");
        //消息发布
        String message="publish/subscript!!";
        channel.basicPublish(EXCHANGE_NAME,"insert",null,message.getBytes());
        //关闭
        channel.close();
        connection.close();
    }
}

 主题模式/通配符模式:

RabbitMQ五种消息模式_第5张图片

这个模式其实是对上一个模式的扩展,上一个模式是说我能接受到路由为insert,update,但是假如我要接收到item的增删改查的消息怎么办呢,难道我要四个绑定4次?那太不友好了,所有这里可以使用咱们的通配符模式:

是需要将交换机类型改成TOPIC 然后 消息队列与消费者进行绑定的时候使用咱们的通配符就好啦

*,# ;*只能代表一个单词再用.进行分割则无法识别 列如:item.* 可以代表item.insert 不能代表:item.insert.name但咱们通配符#可以

package com.shenwang.rabbit.topic;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.shenwang.rabbit.util.RabbitConnectionUtil;

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

/**
 * @author: shenwang
 * Date: 2021/7/6
 */
public class TopicSend {
    public static final String EXCHANGE_NAME="exchange_topic";
    public static void main(String[] args) throws IOException, TimeoutException {
        //建立连接
        Connection connection= RabbitConnectionUtil.getConnection();
        //创建频道
        Channel channel = connection.createChannel();
        /**
         * 申明交换机
         * 参数1:交换机名称
         * 参数2:交换机类型
         */
        channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
        //声明多个队列
        channel.queueDeclare("queue_topic1",true,false,false,null);
        channel.queueDeclare("queue_topic2",true,false,false,null);
        //将交换机与队列进行绑定
        channel.queueBind("queue_topic1",EXCHANGE_NAME,"item.insert");
        channel.queueBind("queue_topic1",EXCHANGE_NAME,"item.update");
        channel.queueBind("queue_topic1",EXCHANGE_NAME,"item.delete");
        channel.queueBind("queue_topic1",EXCHANGE_NAME,"item.*");
        //消息发布
        String message="publish/subscript topic!";
        channel.basicPublish(EXCHANGE_NAME,"item.insert",null,message.getBytes());
        channel.basicPublish(EXCHANGE_NAME,"item.query",null,message.getBytes());
        //关闭
        channel.close();
        connection.close();
    }
}

 这次的文章就分享到这里啦~

自己目前正在学习,所以分享的比较浅

以后我会继续努力的。加油 奥里给!!!

你可能感兴趣的:(rabbitmq,rabbitmq,消息队列)