RabbitMQ入门(一)--RabbitMQ的安装与使用,直连模型demo编写

本文介绍了RabbitMQ的基本概念,通过Docker安装配置RabbitMQ,并展示了直连模型的代码实现,包括消息生产者和消费者的创建。文章强调了消息队列在缓解高频率消息处理压力中的作用。

最近在学习消息队列RabbitMQ相关的知识,打算把自己的理解写下来,包括踩过的坑,记录一下,也分享给大家,欢迎评论区批评指正。话不多说,进入正题……

什么是消息队列

消息队列(Message Queue),本质也是一个队列,所以消息也会符合先进先出的规则。消息队列是一种跨进程的通信机制,被用于上下游传递消息。

RabbitMQ安装和环境配置

安装

我使用的是Docker环境安装的RabbitMQ镜像

# 查询所有的RabbitMQ镜像
docker search rabbitmq
# 安装RabbitMQ
docker pull rabbitmq

# 运行RabbitMQ镜像 -d表示在后台运行 -p端口映射 --name 自定义容器名称 容器ID
docker run -d -p 5672:5672 -p 15672:15672 --name myrabbit

# 查看运行的镜像
docker ps -a

# 启动RabbitMQ
docker start 进程ID

# 安装RabbitMQ插件可以让我们进入到RabbitMQ的管理页面
rabbitmq-plugins enable rabbitmq_shovel rabbitmq_shovel_management

以上就是docker安装的步骤了,在浏览器中输入RabbitMQ主机的IP:15672,如果出现下面的页面,说明咱的RabbitMQ就安装配置成功了。用户名和密码都是guest

RabbitMQ管理登录页

点击login之后会进入到管理的主页面

RabbitMQ管理页面

在这里可以管理连接(Connection)、通道(Channel)、交换机(Exchange)、队列(Queue)等RabbitMQ的主要配置。

Maven项目开发设置

  • 引入依赖

    <!-- 引入RabbitMQ相关依赖 -->
        <!-- https://mvnrepository.com/artifact/com.rabbitmq/amqp-client -->
        <dependency>
          <groupId>com.rabbitmq</groupId>
          <artifactId>amqp-client</artifactId>
          <version>5.9.0</version>
        </dependency>
    
  • RabbitMQ连接工具的封装

    public class RabbitMQUtil {
        // 使用静态资源创建连接MQ的连接工厂对象
        public static ConnectionFactory connectionFactory;
        // 类加载之前只执行一次
        static {
            connectionFactory = new ConnectionFactory();
            // 设置连接RabbitMQ的主机
            connectionFactory.setHost("127.0.0.1");
            // 设置端口号
            connectionFactory.setPort(5672);
            // 设置虚拟主机
            connectionFactory.setVirtualHost("/ems");
            // 设置用户名
            connectionFactory.setUsername("ems");
            // 设置密码
            connectionFactory.setPassword("123");
        }
    
        // 提供创建连接对象的方法
        public static Connection getConnection(){
            try {
                // 获取连接对象
                return connectionFactory.newConnection();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        // 关闭通道和连接的方法
        public static void closeConnectionAndChannel(Channel channel, Connection connection) {
            try {
                if (channel != null) {
                    channel.close();
                }
    
                if (connection != null) {
                    connection.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (TimeoutException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    为了我们连接方便,不用每次在定义publisher和consumer的时候都要写过长的连接代码,这里我们封装了一个工具类。要设置RabbitMQ安装的主机的IP地址(Host)、用户名(username)、密码(password)、虚拟主机(virtualHost)以及虚拟主机的用户名和密码。

    为了避免资源的浪费,在使用完连接和通道之后我们可以关闭通道,所以还封装了关闭连接和通道的方法。

    连接工厂对象是一个高内存占用的资源,如果每次连接都要创建一个对象,十分占用我们的内存,所以我们使用静态资源创建连接MQ的连接工厂对象,静态资源只在类加载的时候初始化一次,这样大大节省了我们的资源占用。

RabbitMQ的模型

HelloWorld–直连模型

直连模型:只有一个生产者和一个消费者,生产者负责生产消息,放入到消息队列中;消费者负责从消息队列中取消息,消费消息。

直连模型

图中P代表生产者,中间红色的部分代表消息队列,C代表消费者。消息队列就是存放消息的缓冲区。

直连模型应该是最容易理解的模型了。与RabbitMQ对比,传统的做法是生产者发布消息,不经过消息队列的缓存,消费者直接消费。这样的做法不适合高频率的消息发送,如果生产者发布消息的频率过快,消费者就会承担消费消息的巨大压力,很容易崩溃。

有了RabbitMQ,生产者发布消息后可以经过消息队列的缓存,消费者再从消息队列中取消息进行消费。这样就避免了消费者承担频率过高的处理工作。

代码实现

消息生产者Publisher

public class Publisher {
    // 声明消息队列的名称
    public static final String QUEUE_NAME = "hello";
    public static void main(String[] args) throws IOException {
        // 获取连接
        Connection connection = RabbitMQUtil.getConnection();
        // 创建通道
        Channel channel = connection.createChannel();
        // 声明绑定队列
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);
        // 消息内容
        String message = "Hello World!";
        // 发布消息
        channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
        System.out.println(" [x] Sent '" + message + "'");
        // 关闭通道和连接
        RabbitMQUtil.closeConnectionAndChannel(channel, connection);
    }
}

==queueDeclare(QUEUE_NAME,false,false,false,null)==方法参数说明:

  • QUEUE_NAME:队列名称,如果队列不存在自动创建
  • false:用来定义队列特性是否要持久化,true–持久化 false–不持久化
  • fasle:exclusive参数表示是否独占队列,true–独占 false–不独占
  • fasle:消息完成后是否自动删除队列,true–自动删除 false–不自动删除
  • null:附加参数,以map形式呈现,如果没有则为null。

==basicPublish("",QUEUE_NAME,null,message.getBytes())==方法参数说明:

  • Exchange:交换机名称,(因为我们的直连模型没有用到交换机,所以这里的参数我们选择为空字符串)
  • QUEUE_NAME:队列名称,表示要把消息发布到哪个消息队列
  • null:传递消息额外设置,如果没有可以选择为空,(MessageProperties.PERSISTENT_TEXT_PLAIN,表示消息内容的持久化)
  • message.getBytes():字节形式的消息内容

消息消费者Consumer

public class Consumer {
    public static final String QUEUE_NAME = "hello";
    public static void main(String[] args) throws IOException {
        // 获取连接并创建通道
        Connection connection = RabbitMQUtil.getConnection();
        Channel channel = connection.createChannel();

        // 绑定对应的消息队列
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);
        // 消费消息
        channel.basicConsume(QUEUE_NAME,true, 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(" [x] Received '" + message + "'");
            }
        });
    }
}

==basicConsume(QUEUE_NAME,true, new DefaultConsumer(channel) {})==方法参数说明:

  • QUEUE_NAME:消息队列的名字,表示要消费哪个队列的消息

  • true:是否开启消息的自动确认机制,true–开启 false–不开启

  • 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(" [x] Received '" + message + "'");
      }
      

创建完消息生产者和消息的消费者,我们就可以进行测试了。首先运行Publisher.java,向消息队列中发送“Hello World!”消息。

生产者输出

发送消息过后,在RabbitMQ的管理页面,可以看到消息队列中创建了名为“hello”的队列,消息队列中的消息数量也从0变成了1。说明我们成功实现了向消息队列中发送消息。

消息队列消息变化

接下来,就是消费者方面。运行Consumer.java,控制台输出如下。说明消息消费者成功输出接收的消息,并在控制台输出成功。

消费者输出

打开RabbitMQ的管理页面,可以发现,名为“hello”的消息队列中的消息数量从1变成了0,说明消息生产者向消息队列中生产的消息被消息消费者进行消费了。

消息队列消息变化

注意生产者和消费者产生中绑定消息队列方法的参数值必须要相同,不然RabbitMQ一定会报错

消息队列绑定参数信息不匹配错误信息

关于RabbitMQ的简单入门就先写这么多了,还有几种经典的模型。上面的直连模型一般是不怎么使用的,不过可以在我们学习RabbitMQ的初级阶段,帮助我们更好的理解消息队列的原理。

如果有错误,请大家评论区批评指正,谢谢大家~

评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值