RabbitMQ

简介
RabbitMQ是一个由Erlang语言开发的AMQP的开源实现,高级消息队列协议即Advanced Message Queuing Protocal,是应用层协议的一个开放标准,为面向消息的中间件设计。主要用于组件之间的解耦,消息的发送者无需知道消息的使用者的存在,使用者也一样。AMQP的主要特征是面向消息、队列、路由(包括点对点的发布/订阅)、可靠性、安全。RabbitMQ是一个开源的AMQP实现,服务器端使用Erlang语言编写,支持多种客户端,如python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。
RabbitMQ概念模型:
消息模型
所有的MQ产品从模型抽象上来说都是一样的过程:
消费者(consumer)订阅某个队列.生产者(producer)创建消息,然后发布到队列(queue)中,最后将消息发送到监听的消费者。

-----------------------------------------------------------------------消息流-------------------------------------------------------------------

RabbitMQ基本概念
具体的RabbitMQ概念详细解释。

1.Message
消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成。这些属性包括routing-key(路由键)、priority(相对于其他消息的优选权)、delivety-mode(指出该消息可能需要持久性存储)等。
2.Publisher
消息的生产者,也是一个向交换器发布消息的客户端应用程序。
3.Exchange
交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。
4.Binding
绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来
的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。
5.Queue
消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。
6.Connection
网络连接,比如一个TCP连接。
7.Channel
信道,多路由复用连接中的一条独立的双向数据流通信。信息时建立在真实的TCP连接内地虚拟连接,AMQP命令都是通过信道发出去的。不管是发布消息、订阅队列还是接收消息,这些动作都是通过信道完成。因为对于操作系统来说建立和销毁TCP的都是非常昂贵的开销,所以引入了信道的概念,已复用一条TCP连接。
8.Consumer
消息的消费者,表示一个从消息队列中获得消息的客户端引用程序。
9.Virtual Host
虚拟主机,表示一批交换器、消息队列和相关对象。虚拟主机是共享相同身份认证和加密环境的独立服务器器域。每个vhost本质上就是一个mini版的RabbitMQ服务器,拥有自己的队列,交换器、绑定和权限机制。vhost是AMQP概念的基础,必须在连接时指定,RabbitMQ默认的vhost是/。
10.Broker
表示消息队列服务器实体。

AMQP中的消息路由
AMQP中消息的路由过程和JMS不一样的是,AMQP中增加了Exchange和Binding角色,生产者把消息发布大Exchange上,消息最终到达队列冰杯消费者接收,二Binding决定交换器的消息应该发送到哪个队列。

1.direct(路由键和队列名完全匹配,单播)

消息中的路由键(routing key)如果和Binding中的binding key 一致,交换器就将消息发到对应的队列中。路由键与队列名完全匹配,如果一个队列绑定到交换器要求路由键为“dog”,则只转发routing key 标记为“dog” 的消息,不会转发“dog.duppy”,也不会转发“dog.guard”等等,它是完全匹配
、单播的模式。
2.fanout

每个发送到fanout类型交换器的消息都会分到所有的绑定的队列上去。fanout交换器不处理路由键,只是简单的将队列绑定到交换器上,每个发送到交换器的的消息都会被转发到与该交换器所绑定的所有队列上。很像子网广播,每台子网内的主机度获得了一份复制的消息。fanout类型转发消息是最快的。
3.topic

topic交换器通过模式匹配分配消息的路由键属性,将路由键和某个模式进行匹配,此时队列需要绑定到一个模式上。它将路由键和绑定键的字符窜切分成单词,这些单词之间用点隔开。她同样会识别两个通配符:符号”#“和符号”“。#匹配0个或多个单词,匹配不多不少一个单词。

安装ReabbitMQ
1安装RabbitMQ之前要安装Erlang
官网下载地址:http://www.erlang.org/downloads
2.安装RabbitMQ
官网下载地址:https://www.rabbitmq.com/download.html
RabbitMQ运行和管理
1.启动
找到安装后的RabbitMQ所在目录下的sbin目录,执行rabbitmq-server即可。
2.后台启动
如果想让RabbitMQ以守护线程的方式在后台运行,可以在启动的时候加上-detached参数
3.查询rabbitMQ状态

在sbin目录下执行命令reabbitmqctl status

4,关闭RabbitMQ节点
我们知道RabbitMQ是用Erlang语言写的,在Erlang中有两个概念:节点和应用程序。节点就是Erlang虚拟机的每个实例,而多个Erlang应用程序可以运行在同一个节点上。节点之间可以进行本地通讯(不管他们是不是运行在同一台服务器之上)。比如一个运行在节点A上的应用程序可以调用节点B上的应用程序上的方法,就好像调用本地函数一样。如果应用程序由于某些原因奔溃,Erlang节点会自动尝试重启应用程序。
如果要关闭整个RabbitMQ节点可以调用参数stop:

在sbin目录下执行命令reabbitmqctl stop

它会和本地节点通信并指示其干净的关闭,也可以指定关闭不同的节点,包括远程节点,只需要传入参数-n

rabbitmqctl -n rabbit@server.example.com stop

-n node默认node名称默认是rabbit@server,如果你的主机名是server.example.com,那么node名称就是rabbit@server.example.com。
5.关闭RabbitMQ应用程序
如果只想关闭应用程序,同时保持Erlang节点运行则可以用stop_app

在sbin目录下执行命令reabbitmqctl stop_app

6.启动RabbitMQ应用程序

在sbin目录下执行命令reabbitmqctl start_app

7.重置RabbitMQ节点

在sbin目录下执行命令reabbitmqctl reset

该命令将清除所有的队列
8.查看已声明的队列

在sbin目录下执行命令reabbitmqctl list_queues

9.查看交换器

在sbin目录下执行命令reabbitmqctl list_exchanges

该命令还可以附加参数,比如列出交换器的名称、类型、是否持久化、是否自动删除

在sbin目录下执行命令reabbitmqctl list_exchanges name type durable auto_delete

10.查看绑定

在sbin目录下执行命令reabbitmqctl list_bindings

Java客户端访问
1.maven工程的pom文件中添加依赖

<dependency><groupId>com.rabbitmq</groupId><artifactId>amqp-client</artifactId><version>4.1.0</version>
</dependency>

2.消息生产者

package com.wuxian.study.rabbitmq;import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import lombok.SneakyThrows;import java.io.IOException;
import java.util.concurrent.TimeoutException;/*** @Author 王敏霞* @Date 2021/12/13  11:59*/
public class Producer {public static void main(String[] args) throws IOException, TimeoutException {
//        创建连接工厂ConnectionFactory factory=new ConnectionFactory();factory.setUsername("guest");factory.setPassword("guest");
//        设置RabbitMQ地址factory.setHost("localhost");
//        建立到代理服务器到连接Connection conn=factory.newConnection();
//        获得信道Channel channel = conn.createChannel();String exchangeName="hello-exchange";channel.exchangeDeclare(exchangeName,"direct",true);String routingKey="jiangc";
//        发布消息byte[] messageBodyBytes="quit".getBytes();channel.basicPublish(exchangeName,routingKey,null,messageBodyBytes);channel.close();conn.close();}
}

3.消息消费者

package com.wuxian.study.rabbitmq;import com.rabbitmq.client.*;import java.io.IOException;
import java.util.concurrent.TimeoutException;/*** @Author 王敏霞* @Date 2021/12/13  11:59*/
public class Consumer {public static void main(String[] args) throws IOException, TimeoutException {ConnectionFactory factory=new ConnectionFactory();factory.setUsername("guest");factory.setPassword("guest");factory.setHost("localhost");
//        建立到代理服务器到连接Connection conn=factory.newConnection();
//        获得信道Channel channel = conn.createChannel();
//        声明交换器String exchangeName="hello-exchange";channel.exchangeDeclare(exchangeName,"direct",true);
//        声明队列String queueName=channel.queueDeclare().getQueue();String routingKey="jiangc";
//        绑定队列 通过键jiangc将队列和交换器绑定起来channel.queueBind(queueName,exchangeName,routingKey);while (true) {
//            消费消息boolean autoAck = false;String consumerTag = "";channel.basicConsume(queueName, autoAck, consumerTag, new DefaultConsumer(channel) {@Overridepublic void handleDelivery(String consumerTag,Envelope envelope,AMQP.BasicProperties properties,byte[] body) throws IOException {String routingKey = envelope.getRoutingKey();String contentType = properties.getContentType();System.out.println("消费的路由键:" + routingKey);System.out.println("消费的内容类型:" + contentType);long deliveryTag = envelope.getDeliveryTag();//确认消息channel.basicAck(deliveryTag, false);System.out.println("消费的消息体内容:");String bodyStr = new String(body, "UTF-8");System.out.println(bodyStr);}});}}
}

4.启动RabbitMQ服务器
在sbin目录下执行命令 rabbitmq-server
5.运行Consumer
先运行Consumer,这样当生产者发送消息的时候能在消费者后端看到消息记录。
6.运行Producer
接着运行Producer,发布一条消息,在Consumer的控制台能看到接收的消息:

RabbitMQ集群
RabbitMQ最优秀的功能之一就是内建集群,这个功能设计的目的是允许消费者和生产者在节点崩溃的情况下继续运行,以及通过添加更多的节点来线性扩展消息通信吞吐量。RabbitMQ内部利用Erlang提供的分布式通信框架OTP来满足需求,使客户端在失去一个RabbitMQ节点连接的情况下,还是能够重新连接到集群中的任何其他节点继续生产、消费提醒。
RabbitMQ集群概念
RabbitMQ会始终记录以下四种类型的内部元数据:
1.队列元数据
包括队列名称和它们的属性,比如是否可持久化,是否自动删除
2.交换器元数据
交换器名称、类型、属性
3.绑定元数据
内部是一张表格记录如何将消息路由到队列
4.vhost
为vhost内部的队列、交换器、绑定提供命名空间和安全属性

在单一节点中,RabbitMQ会将所有的这些文件存储到内存中,同时将标记为可持久化的队列、
交换器、绑定存储到硬盘上。存到硬盘上可以确保队列和交换器在节点重启后能够重建。而在集群模式下同样也提供两种选择:存到硬盘上(独立节点的默认设置),存在内存中。

如果再集群中创建队列,集群只会在单个节点而不是所有节点上创建完整的队列信息(元数据、状态、内容)。结果是只有队列的所有子节点知道有关队列的所有信息。因此当集群节点崩溃时,该节点的队列和绑定就消失了,并且任何匹配该队列的绑定的新消息也丢失了。还好RabbitMQ2.6.0之后提供了镜像队列以避免集群节点故障导致的队列内容不可用。

RabbitMQ集群中可以共享user、vhost、exchange等,所有的数据和状态都是必须在所有节点上复制的,列外就是上面所说的消息队列。RabbitMQ节点可以动态的加入到集群中。

当在集群中声明队列、交换器、绑定的时候,这些操作会直到所有集群节点都成功提交元数据变更后才返回。集群中有内存节点和磁盘节点两种类型,内存节点虽然不写入磁盘,但是它的执行比磁盘节点摇号。内存节点可以提供出色的性能,磁盘节点能保障配置信息在节点重启后仍然可用,那集群中如何平衡这两者呢?

RabbitMQ只要求集群中至少有一个磁盘节点,所有其他节点可以是内存节点,当节点加入后离开集群时,它们必须要将该变更通知到至少一个磁盘节点。如果只有一个磁盘节点,刚好又是该节点崩溃了,那么集群可以继续路由消息,但不能创建队列、创建交换器、创建绑定、添加用户、更改权限、添加或删除集群节点。还句话说集群中的唯一磁盘节点奔溃的话,集群人可以运行,直到崩溃的磁盘节点恢复。否则无法更改任何东西。

学习时查看简书做的笔记:https://www.jianshu.com/p/79ca08116d57

初探RabbitMQ与简单实现相关推荐

  1. 初探 RabbitMQ 消息队列

    初探 RabbitMQ 消息队列 rabbitmq基础概念常见应用场景导入依赖属性配置具体编码定义队列实体类控制器消息消费者主函数测试总结说点什么 SpringBoot 是为了简化 Spring 应用 ...

  2. 基于消息中间件RabbitMQ实现简单的RPC服务

    转载自  基于消息中间件RabbitMQ实现简单的RPC服务 RPC(Remote Procedure Call,远程过程调用),是一种计算机通信协议.对于两台机器而言,就是A服务器上的应用程序调用B ...

  3. docker安装rabbitmq及简单管理

    docker安装rabbitmq及简单管理 rabbitmq镜像下载与安装 1.docker search rabbitmq 命令说明:从docker仓库搜索rabbitmq的镜像,类似maven的中 ...

  4. RabbitMq之简单队列

    这里写了一个简单的springboot的demo来处理RabbitMq的简单队列 记录一下步骤. 添加pom依赖 <dependency><groupId>com.rabbit ...

  5. python对RabbitMQ的简单使用

    python对RabbitMQ的简单使用 (一)RabbitMQ的简介 (二)RabbitMQ的安装 (三)python操作RabbitMQ (四)RabbitMQ简单模式 (五)RabbitMQ发布 ...

  6. RabbitMQ初探--用C#简单实现通信服务

    MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们. 消息传递指的是程序之 ...

  7. RabbitMQ的简单使用

    一.认识MQ 1.同步和异步通讯 微服务间通讯有同步和异步两种方式: 同步通讯:就像打电话,需要实时响应. 异步通讯:就像发邮件,不需要马上回复. 两种方式各有优劣,打电话可以立即得到响应,但是你却不 ...

  8. adb push命令传文件到手机_ADB初探 —— 几行简单的命令来控制你的Android手机

    Android系统在平台的开放性上是领先iOS的,凭借自身的可扩展性和定制性,不同的厂商推出了独具品牌特色的ROM,比如小米的MIUI,华为的EMUI,魅族的FlyMe等等.Android的日常开发中 ...

  9. 初探RabbitMQ

    官网 安装教程视频 安装 简单模式入门案例 环境搭建 生产者代码 消费者代码 测试 工作队列模式入门案例 创建公共类(复用代码) 消费者代码 生产者代码 测试 消息应答 自动应答 手动应答 消息自动重 ...

最新文章

  1. android listview edittext 焦点冲突,Android开发之ListView+EditText-要命的焦点和软键盘问题解决办法...
  2. python将图像转换为8位单通道_Python OpenCV读取16位单通道图像并转换为8位灰度图显示...
  3. gram矩阵的性质_线性代数(十五)标准正交基(Orthonormal Bases)和Gram-Schmidt正交化...
  4. Java 实现单例模式的 9 种方法
  5. RESTful Web 服务 - 寻址
  6. SAP Hybris安装包里自带的apache ant
  7. easy js test--方便对js进行测试,不需要刷新
  8. Vue2.0 全家桶开发的网页应用(参照吾记APP)
  9. 用jquery在一个页面加载另一个页面
  10. NSight统计数据的颜色,缩写意义是什么?来自NV Jeff Kiel 比较官方的解释!
  11. 实现数据库连接池druid的工具类
  12. 华为光猫虚拟服务器怎么设置,华为路由器连接光猫怎么设置
  13. pycharm 文件名颜色所代表的含义
  14. 量化策略“高股息率模型”长期有效性的实证
  15. 有限域f9的特征是多少_机械公差f9的上下偏差各是多少啊?
  16. NRF51822的蓝牙设置
  17. 网络计算机无法连接打印机,网络打印机无法连接怎么办 网络打印机无法连接教程【详解】...
  18. jquery实现二级导航下拉菜单效果实例
  19. postgresql中patroni集群备库手动还原后,hac启动日志比主库多1
  20. CVBS/AHD 转换 BT656/BT601

热门文章

  1. 电游入侵传统教育,用练级学习
  2. 人工智能在游戏设计中的应用
  3. 教你几种方法最大限度减轻酒精对你身体的伤害
  4. Pygame详解(二):display 模块
  5. VS2017搭建linux开发环境
  6. 字符类型与整形之间的转换
  7. 车牌对应城市行政区编号
  8. Altium Designer PCB封装库放置3D模型对齐问题的解决思路
  9. Ubuntu安装Caffe .build_release/tools/caffe: error while loading shared libraries: libcudart.so.8.0
  10. [解决] 钉钉小程序提示 ‘dd is not defined‘