【RabbitMQ】消息队列-RabbitMQ篇章

文章目录

1、RabbitMQ是什么

RabbitMQ是一个开源的遵循AMQP协议实现的基于Erlang语言编写,支持多种客户端(语言)。用于在分布式系统中存储消息,转发消息,具有高可用高可扩性易用性等特征。

2、Dokcer安装RabbitMQ

2.1安装Dokcer

  1. yum 包更新到最新
bash 复制代码
> yum update
  1. 安装软件包,yum-util提供yum-config-manager功能,另外两个是devicemapper驱动依赖的
bash 复制代码
> yum install -y yum-utils device-mapper-persistent-data lvm2
  1. 设置yum源为阿里云
bash 复制代码
> yum-config-manager --add-repo
> http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  1. 安装docker
bash 复制代码
> yum install docker-ce-y
  1. 安装后查看docker版本
bash 复制代码
> docker-v
  1. 安装加速镜像

从阿里云获取镜像加速器:
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors

bash 复制代码
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://spukdfwp.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docke

2.2安装rabbitmq

  1. 路径:https://www.rabbitmq.com/download.html
  1. 点击上图中标红线的 community Docker
    image,跳转到如下地址:https://registry.hub.docker.com/_/rabbitmq/

当前可以看到安装镜像的时候可以设置用户名,密码,ip。就不用安装完进入容器内部设置

  1. 官网给的安装案例
bash 复制代码
$ docker run -d --hostname my-rabbit --name some-rabbit -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password rabbitmq:3-management

4.命令讲解

bash 复制代码
docker run -id --hostname my-rabbit --name=myrabbit -p 15672:15672 rabbitmq:3-management

--hostname:指定容器主机名称
--name:指定容器名称
-p:将mq端口号映射到本地
-e 设置

5.修改命令创建并安装

bash 复制代码
docker run -di  --name myrabbit -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=admin -p 15672:15672 -p 5672:5672 -p 25672:25672 -p 61613:61613 -p 1883:1883 rabbitmq:3-management

6.阿里云开放上方命令 设置的端口号

bash 复制代码
-p 15672:15672 -p 5672:5672 -p 25672:25672 -p 61613:61613 -p 1883:1883

7.安装成功

bash 复制代码
[root@iZbp1av1izm1qqcdfa0nndZ ~]# docker images
REPOSITORY   TAG            IMAGE ID       CREATED        SIZE
rabbitmq     3-management   6c3c2a225947   7 months ago   253MB
[root@iZbp1av1izm1qqcdfa0nndZ ~]# docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED         STATUS         PORTS                                                                                                                                                                                                                                                                               NAMES
1de1f1e10cb0   rabbitmq:3-management   "docker-entrypoint.s..."   6 minutes ago   Up 6 minutes   4369/tcp, 0.0.0.0:1883->1883/tcp, :::1883->1883/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, :::5672->5672/tcp, 15671/tcp, 0.0.0.0:15672->15672/tcp, :::15672->15672/tcp, 0.0.0.0:25672->25672/tcp, :::25672->25672/tcp, 0.0.0.0:61613->61613/tcp, :::61613->61613/tcp, 15691-15692/tcp   myrabbit
[root@iZbp1av1izm1qqcdfa0nndZ ~]#

8.停掉手动安装的rabbimq

bash 复制代码
systemctl stop rabbitmq-server

9.启动docker的rabbitmq容器

bash 复制代码
##查看容器
[root@iZbp1av1izm1qqcdfa0nndZ ~]# docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED         STATUS         PORTS                                                                                                                                                                                                                                                                               NAMES
1de1f1e10cb0   rabbitmq:3-management   "docker-entrypoint.s..."   9 minutes ago   Up 9 minutes   4369/tcp, 0.0.0.0:1883->1883/tcp, :::1883->1883/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, :::5672->5672/tcp, 15671/tcp, 0.0.0.0:15672->15672/tcp, :::15672->15672/tcp, 0.0.0.0:25672->25672/tcp, :::25672->25672/tcp, 0.0.0.0:61613->61613/tcp, :::61613->61613/tcp, 15691-15692/tcp   myrabbit
##启动容器 docker start 容器id(CONTAINER ID)
[root@iZbp1av1izm1qqcdfa0nndZ ~]# docker start 1de1f1e10cb0
1de1f1e10cb0
[root@iZbp1av1izm1qqcdfa0nndZ ~]#

10.通过服务器(虚拟机ip+端口号(15672))访问RabbitMQ主页http://192.168.157.128:15672

默认登录账号和密码都是admin

并且在admin账号下可以通过增加用户,给用户不同角色,也就对应不同的操作权限:

详情如下:

3、RabbitMQ入门案例 - Simple 简单模式

1.实现步骤:

bash 复制代码
1:jdk1.8
2:构建一个maven工程
3:导入rabbitmq的maven依赖
4:启动rabbitmq-server服务
5:定义生产者
6:定义消费者
7:观察消息的在rabbitmq-server服务中的过程

2.构建一个maven工程

3.导入rabbitmq的maven依赖

bash 复制代码
<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>5.10.0</version>
</dependency>


<dependency>
    <groupId>org.springframework.amqp</groupId>
    <artifactId>spring-amqp</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.amqp</groupId>
    <artifactId>spring-rabbit</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>



<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

4.启动rabbitmq-server服务

bash 复制代码
systemctl start rabbitmq-server
或者
docker start myrabbit

5、定义生产者

java 复制代码
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class Producer {
    public static void main(String[] args) {
        // 1: 创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: 设置连接属性
        connectionFactory.setHost("192.168.157.128");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: 从连接工厂中获取连接
            connection = connectionFactory.newConnection("生产者");
            // 4: 从连接中获取通道channel
            channel = connection.createChannel();
            // 5: 申明队列queue存储消息
            /*
             *  如果队列不存在,则会创建
             *  Rabbitmq不允许创建两个相同的队列名称,否则会报错。
             *
             *  @params1: queue 队列的名称
             *  @params2: durable 队列是否持久化
             *  @params3: exclusive 是否排他,即是否私有的,如果为true,会对当前队列加锁,其他的通道不能访问,并且连接自动关闭
             *  @params4: autoDelete 是否自动删除,当最后一个消费者断开连接之后是否自动删除消息。
             *  @params5: arguments 可以设置队列附加参数,设置队列的有效期,消息的最大长度,队列的消息生命周期等等。
             * */
            channel.queueDeclare("queue1", false, false, true, null);
            // 6: 准备发送消息的内容
            String message = "你好,学相伴!!!";
            // 7: 发送消息给中间件rabbitmq-server
            // @params1: 交换机exchange
            // @params2: 队列名称/routing
            // @params3: 属性配置
            // @params4: 发送消息的内容
            channel.basicPublish("", "queue1", null, message.getBytes());
            System.out.println("消息发送成功!");
        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("发送消息出现异常...");
        } finally {
            // 7: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            // 8: 关闭连接
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

1:执行发送,这个时候可以在web控制台查看到这个队列queue的信息

2:我们可以进行对队列的消息进行预览和测试如下:

3:进行预览和获取消息进行测试

NACK 只是做消息预览,不会吧消息从队列移除
ACK相当于手动的把消息处理了,这个时候就会把消息从队列剔除,导致消息丢失

6、定义消费者

java 复制代码
import com.rabbitmq.client.*;

import java.io.IOException;

public class Consumer {
    public static void main(String[] args) {
        // 所有的中间件技术都是基于tcp/ip协议基础上构建新型协议规范,只不过rabbitmq遵循的是amqp
        // ip port

        // 1: 创建连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        // 2: 设置连接属性
        connectionFactory.setHost("192.168.157.128");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        connectionFactory.setUsername("admin");
        connectionFactory.setPassword("admin");
        Connection connection = null;
        Channel channel = null;
        try {
            // 3: 从连接工厂中获取连接
            connection = connectionFactory.newConnection("消费者");
            // 4: 从连接中获取通道channel
            channel = connection.createChannel();

            channel.basicConsume("queue1", true, new DeliverCallback() {
                public void handle(String consumerTag, Delivery message) throws IOException {
                    System.out.println("收到的消息是:" + new String(message.getBody(), "UTF-8"));
                }
            }, new CancelCallback() {
                public void handle(String s) throws IOException {
                    System.out.println("接收失败了。。。");
                }
            });
            System.out.println("开始接收消息");
            System.in.read();
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("发送消息出现异常...");
        }finally {
            // 7: 释放连接关闭通道
            if (channel != null && channel.isOpen()) {
                try {
                    channel.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }
    }
}

消费者和生产者的区别在于,消费者是从mq中取消息,而生产者是从mq中存消息

4、RabbitMQ的核心组成部分


核心概念:

  1. Server:又称Broker ,接受客户端的连接,实现AMQP实体服务。 安装rabbitmq-server
  2. Connection:连接,应用程序与Broker的网络连接 TCP/IP/ 三次握手和四次挥手
  3. Channel:网络信道,几乎所有的操作都在Channel中进行,Channel是进行消息读写的通道,客户端可以建立对各Channel,每个Channel代表一个会话任务。
  4. Message:消息:服务与应用程序之间传送的数据,由Properties和body组成,Properties可是对消息进行修饰,比如消息的优先级,延迟等高级特性,Body则就是消息体的内容。
  5. Virtual Host 虚拟地址,用于进行逻辑隔离,最上层的消息路由,一个虚拟主机理由可以有若干个Exhange和Queueu,同一个虚拟主机里面不能有相同名字的Exchange
  6. Exchange :交换机,接受消息,根据路由键发送消息到绑定的队列。(不具备消息存储的能力)
  7. Bindings:Exchange和Queue之间的虚拟连接,binding中可以保护多个routing key.
  8. Routing key:是一个路由规则,虚拟机可以用它来确定如何路由一个特定消息。
  9. Queue:队列:也成为Message Queue,消息队列,保存消息并将它们转发给消费者。

4.1 RabbitMQ整体架构

4.2RabbitMQ的运行流程

所以发送消息的时候没有设置交换机,rabbitmq发送消息一定会有默认一个交换机,并且消息不是直接到队列当中的,而是由交换机根据路由键发送消息到绑定的队列


5、RabbitMQ的模式

5.1 发布订阅模式--fanout

特点:Fanout---发布与订阅模式,是一种广播机制,它是没有路由key的模式。

也就是只要生产者发送一条消息经过交换机加入队列中,左右的消费者都能拿到消息

这里就直接用web界面演示

  1. 新建一个fanout模式的交换机(让交换机代替生产者去发消息)

  2. 创建3个消息队列q1、q2、q3

  3. 将队列绑定到交换机上

  4. 由交换机代替生产者发送消息

  5. 然后三个队列都会有一个交换机发来的消息

  6. q1队列消息正常被消费者拾取(其他队列一样)

  7. q1队列消息正常被消费者拾取之后,队列消息-1

    ACK后 页面在自动会更新队列消息条目,默认5秒

更新中------

参考来自:狂神

相关推荐
腥臭腐朽的日子熠熠生辉39 分钟前
解决maven失效问题(现象:maven中只有jdk的工具包,没有springboot的包)
java·spring boot·maven
ejinxian41 分钟前
Spring AI Alibaba 快速开发生成式 Java AI 应用
java·人工智能·spring
杉之1 小时前
SpringBlade 数据库字段的自动填充
java·笔记·学习·spring·tomcat
圈圈编码1 小时前
Spring Task 定时任务
java·前端·spring
俏布斯1 小时前
算法日常记录
java·算法·leetcode
27669582921 小时前
美团民宿 mtgsig 小程序 mtgsig1.2 分析
java·python·小程序·美团·mtgsig·mtgsig1.2·美团民宿
爱的叹息1 小时前
Java 连接 Redis 的驱动(Jedis、Lettuce、Redisson、Spring Data Redis)分类及对比
java·redis·spring
程序猿chen2 小时前
《JVM考古现场(十五):熵火燎原——从量子递归到热寂晶壁的代码涅槃》
java·jvm·git·后端·java-ee·区块链·量子计算
松韬2 小时前
Spring + Redisson:从 0 到 1 搭建高可用分布式缓存系统
java·redis·分布式·spring·缓存
绝顶少年2 小时前
Spring Boot 注解:深度解析与应用场景
java·spring boot·后端