RabbitMQ各种模式及其confirm模式、return模式、ack机制说明、限流、TTL、死信队列、延迟队列实现

本文详细介绍了RabbitMQ的安装过程,包括Erlang和RabbitMQ的下载与配置。接着,讲解了RabbitMQ的基本概念,如生产者、消费者、broker、虚拟主机和队列。还展示了RabbitMQ管理控制台的使用,包括用户、权限和队列的管理。然后,通过代码示例展示了RabbitMQ的工作模式,包括简单模式、工作队列模式、发布订阅模式(广播和路由)。此外,还讨论了SpringBoot如何与RabbitMQ整合。最后,探讨了RabbitMQ的高级特性,如生产者和消费者的可靠性、消费端限流、TTL和死信队列等。

Rabbitmq

1、下载安装

**第一步:**下载安装erlang,RabbitMQ服务端代码是使用并发式语言Erlang编写的,安装Rabbit MQ的前提是安装Erlang。

下载地址:http://www.erlang.org/downloads

选择自己合适的版本进行下载,在安装时记得记住安装路径,安装完事儿后要记得配置一下系统的环境变量

此电脑–>鼠标右键“属性”–>高级系统设置–>环境变量–>“新建”系统环境变量

image-20210830085402676

变量名:ERLANG_HOME,变量值就是刚才erlang的安装地址,点击确定。

双击系统变量path,点击“新建”,将%ERLANG_HOME%\bin加入到path中。

image-20210830085517841

最后windows键+R键,输入cmd,再输入erl,看到版本号就说明erlang安装成功了。

image-20210830085607048

第二步:安装rabbitmq

下载地址:http://www.rabbitmq.com/download.html

  • 双击下载后的.exe文件,安装过程与erlang的安装过程相同。
  • RabbitMQ安装好后接下来安装RabbitMQ-Plugins。打开命令行cd,输入RabbitMQ的sbin目录。

cmd到rabbitmq-server的 sbin目录下 打开cmd命令行工具

cd C:\Program Files\RabbitMQ Server\rabbitmq_server-3.7.4\sbin

执行命令:

rabbitmq-plugins.bat enable rabbitmq_management

image-20210830090056212

重启rabbitmq服务器:

此电脑–》右击 点击管理界面–》双击服务和应用程序–》双击 服务–》点击重启按钮即可

image-20210830090247715

浏览器中输入localhost:15672 输 guest/guest

image-20210830090257028

2、概念说明

image-20210830092104984

其中的概念有:

  • 生产者:发送消息的一方 producer
  • 消费者:接收消息的一方 consumer
  • broker:用来存储信息的逻辑概念的组件
  • 虚拟主机:VirtualHosts,使用来区分不用的业务的组件
  • queue:真正存储消息的组件(队列)

3、界面介绍

admin选项卡中就代表的是用户界面:

image-20210830092607155

其中下面的add a user就可以添加用户:

image-20210830092718440

我们创建一个名为zhangsan的用户

角色说明

1、 超级管理员(administrator)

可登陆管理控制台,可查看所有的信息,并且可以对用户,策略(policy)进行操作。

2、 监控者(monitoring)

可登陆管理控制台,同时可以查看rabbitmq节点的相关信息(进程数,内存使用情况,磁盘使用情况等)

3、 策略制定者(policymaker)

可登陆管理控制台, 同时可以对policy进行管理。但无法查看节点的相关信息(上图红框标识的部分)。

4、 普通管理者(management)

仅可登陆管理控制台,无法看到节点信息,也无法对策略进行管理。

5、 其他

无法登陆管理控制台,通常就是普通的生产者和消费者。

然后上面的User列表中就会出现一个新的用户:

image-20210830100046062

可以看见zhangsan用户没有自己虚拟主机,此时我们可以给zhangsan分配一个虚拟主机,名字是pay,也就是支付相关的:

image-20210830100655005

点入pay中可以设置权限:

image-20210830100839677

设置完后:

image-20210830100932859

参数说明:

  • user:用户名
  • configure :一个正则表达式,用户对符合该正则表达式的所有资源拥有 configure 操作的权限
  • write:一个正则表达式,用户对符合该正则表达式的所有资源拥有 write 操作的权限
  • read:一个正则表达式,用户对符合该正则表达式的所有资源拥有 read 操作的权限

配置完后,zhangsan就有了pay虚拟主机:

image-20210830101109551

4、RabbitMQ入门

添加依赖:

<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>5.6.0</version>
</dependency>
4.1、消费者

生产者的创建分为如下几个步骤:

//创建链接工厂对象
//设置RabbitMQ服务主机地址,默认localhost
//设置RabbitMQ服务端口,默认5672
//设置虚拟主机名字,默认/
//设置用户连接名,默认guest
//设置链接密码,默认guest
//创建链接
//创建频道
//声明队列
//创建消息
//消息发送
//关闭资源

按照上面的步骤,我们创建一个消息生产者,

package com.yxinmiracle.simple;

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

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

/**
 * @version 1.0
 * @author: YxinMiracle
 * @date: 2021-08-30 10:22
 */

public class Producer {
   
   

    // 发送消息
    public static void main(String[] args) throws IOException, TimeoutException {
   
   
        // 创建工厂对象
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 设置RabbitMq服务器主机
        connectionFactory.setHost("localhost");
        // 设置端口
        connectionFactory.setPort(5672);
        // 设置虚拟主机名字
        connectionFactory.setVirtualHost("/pay");
        connectionFactory.setUsername("zhangsan");
        connectionFactory.setPassword("zhangsan");
        Connection connection = connectionFactory.newConnection();
        // 创建频道
        Channel channel = connection.createChannel();

        // 创建队列
        /*
        * 1. 参数1: 制定队列的名称
        * 2. 参数2: 制定是否持久化,一般为true
        * 3. 参数3:是否独占这个通道,一般选择不独占
        * 4. 参数4:指定是否自动删除
        * 5. 参数5:指定额外的参数
        * */
        channel.queueDeclare("simple_queue1",true,false,false,null);
        // 创建消息
        String msg = "hello i am from simple producer";

        // 消息发送
        /*
        * 1. 参数1: 指定交换机 简单模式中使用默认的交换机 指定空字符串
        * 2. 参数2: 简单模式就是队列名称
        * 3. 参数3: 指定携带的额外的参数 null
        * 4. 发送的消息本身
        * */
        channel.basicPublish("","simple_queue1",null,msg.getBytes());

        channel.close();
        connection.close();
    }
}

在执行上述的消息发送之后;可以登录rabbitMQ的管理控制台,可以发现队列和其消息:

image-20210830111510703

如果想查看消息,可以点击队列名称->Get Messages,如下图:

image-20210830111334742

4.2、消费者

消费者创建可以按照如下步骤实现:

//创建链接工厂对象
//设置RabbitMQ服务主机地址,默认localhost
//设置RabbitMQ服务端口,默认5672
//设置虚拟主机名字,默认/
//设置用户连接名,默认guest
//设置链接密码,默认guest
//创建链接
//创建频道
//创建队列
//创建消费者,并设置消息处理
//消息监听
//关闭资源(不建议关闭,建议一直监听消息)

按照上面的步骤创建消息消费者:

package com.yxinmiracle.simple;

import com.rabbitmq.client.*;

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

/**
 * @version 1.0
 * @author: YxinMiracle
 * @date: 2021-08-30 10:23
 */

public class Consumer {
   
   
    public static void main(String[] args) throws IOException, TimeoutException {
   
   
        // 创建工厂对象
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 设置RabbitMq服务器主机
        connectionFactory.setHost("localhost");
        // 设置端口
        connectionFactory.setPort(5672);
        // 设置虚拟主机名字
        connectionFactory.setVirtualHost("/pay");
        connectionFactory.setUsername("zhangsan");
        connectionFactory.setPassword("zhangsan");
        Connection connection = connectionFactory.newConnection();
        // 创建频道
        Channel channel = connection.createChannel();
        // 监听队列
        channel.queueDeclare("simple_queue1",true,false,false,null);

        // 创建消费者,并设置处理消息
        DefaultConsumer consumer = new DefaultConsumer(channel){
   
   
            // 重写父类方法,接收到消息之后要进行处理消息
            /***
             * @param consumerTag   消息者标签,在channel.basicConsume时候可以指定
             * @param envelope      消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)
             * @param properties    属性信息
             * @param body           消息
             * @throws IOException
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
   
   
                //路由的key
                String routingKey = envelope.getRoutingKey();
                //获取交换机信息
                String exchange = envelope.getExchange();
                //获取消息ID
                long deliveryTag = envelope.getDeliveryTag();
                //获取消息信息
                String message = new String(body,"UTF-8");
                System.out.println("routingKey:"+routingKey+",exchange:"+exchange+",deliveryTag:"+deliveryTag+",message:"+message);

            }
        };

        // 消息监听
        channel.basicConsume("simple_queue1",true,consumer);

    }
}

运行后控制台打印:

image-20210830111655030

4.3、工具类的抽取

工具类抽取

无论是消费者,还是生产者,我们发现前面的几个步骤几乎一模一样,所以可以抽取一个工具类,将下面这段代码抽取出去。

创建工具类,用于创建Connection,代码如下:

package com.yxinmiracle.utils;

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

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

/**
 * @version 1.0
 * @author: YxinMiracle
 * @date: 2021-08-30 11:23
 */
public class ConnectionUtil {
   
   

    /***
     * 创建链接对象
     * @return
     * @throws IOException
     * @throws TimeoutException
     */
    public static Connection getConnection() throws IOException, TimeoutException {
   
   
        //创建链接工厂对象
        ConnectionFactory connectionFactory = new ConnectionFactory();

        //设置RabbitMQ服务主机地址,默认localhost
        connectionFactory.setHost("localhost");

        //设置RabbitMQ服务端口,默认5672
        connectionFactory.setPort(5672);

        //设置虚拟主机名字,默认/
        connectionFactory.setVirtualHost("/pay");

        //设置用户连接名,默认guest
        connectionFactory.setUsername("zhangsan");

        //设置链接密码,默认guest
        connectionFactory.setPassword("zhangsan");

        //创建链接
        Connection connection = connectionFactory.newConnection();
        return connection;
    }
}

5、工作模式

链接:https://rabbitmq.com/getstarted.html,通过这个网站可以查看官方所说的所有模式:

image-20210830111954818

image-20210830112950881

5.1、Work queues工作队列模式
5.1.1 模式说明

image-20210830141905532

Work Queues与入门程序的简单模式相比,多了一个或一些消费端,多个消费端共同消费同一个队列中的消息。

应用场景:对于 任务过重或任务较多情况使用工作队列可以提高任务处理的速度。

5.1.2 代码

Work Queues与入门程序的简单模式的代码是几乎一样的;可以完全复制,并复制多一个消费者进行多个消费者同时消费消息的测试。

(1)生产者

创建消息生产者对象,代码如下:

package com.yxinmiracle.work;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.yxinmiracle.utils.ConnectionUtil;

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

/**
 * @version 1.0
 * @author: YxinMiracle
 * @date: 2021-08-30 11:27
 */

public class Producer {
   
   
    public static void main(String[] args) throws IOException, TimeoutException {
   
   
        Connection connection = ConnectionUtil.getConnection();
        // 创建频道
        Channel channel = connection.createChannel();

        // 创建队列
        /*
         * 1. 参数1: 制定队列的名称
         * 2. 参数2: 制定是否持久化,一般为true
         * 3. 参数3:是否独占这个通道,一般选择不独占
         * 4. 参数4:指定是否自动删除
         * 5. 参数5:指定额外的参数
         * */
        channel.queueDeclare("simple_queue2",true,false,false,null);

        for (int i = 0; i < 20; i++) {
   
   
            // 创建消息
            String msg = "hello i am from simple producer";

            // 消息发送
            /*
             * 1. 参数1: 指定交换机 简单模式中使用默认的交换机 指定空字符串
             * 2. 参数2: 简单模式就是队列名称
             * 3. 参数3: 指定携带的额外的参数 null
             * 4. 发送的消息本身
             * */
            channel.basicPublish("","simple_queue2",null,msg.getBytes());
        }

        channel.close();
        connection.close();
    }
}

(2)消费者One

创建第1个Work消费者,代码如下:

public class WorkConsumerOne {
   
   

    /***
     * 消息消费者
     * @param args
     * @throws IOException
     * @throws TimeoutException
     */
    public static void main(String[] args) throws IOException, TimeoutException {
   
   
        //创建链接
        Connection connection = ConnectionUtil.getConnection();

        //创建频道
        Channel channel = connection.createChannel();

        //创建队列
        channel.queueDeclare("work_queue",true,false,false,null);

        //创建消费者,并设置消息处理
        DefaultConsumer defaultConsumer = new DefaultConsumer(channel){
   
   
            /***
             * @param consumerTag   消息者标签,在channel.basicConsume时候可以指定
             * @param envelope      消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)
             * @param properties    属性信息
             * @param body           消息
             * @throws IOException
             */
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
   
   
                //路由的key
                String routingKey = envelope.getRoutingKey();
                //获取交换机信息
                String exchange = envelope.getExchange();
                //获取消息ID
                long deliveryTag = envelope.getDeliveryTag();
                //获取消息信息
                String message = new String(body,"UTF-8");
                System.out.println("Work-One:routingKey:"+routingKey+",exchange:"+exchange+",deliveryTag:"+deliveryTag+",message:"+message);
            }
        };

        /**
         * 消息监听
         * 参数1:队列名称
         * 参数2:是否自动确认,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动确认
         * 参数3:消息接收到后回调
         */
        channel.basicConsume("work_queue",true,defaultConsumer);

        //关闭资源(不建议关闭,建议一直监听消息)
        //channel.close();
        //connection.close();
    }
}

(3)消费者

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值